package com.rt.schedulenew.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.rt.schedulebase.dto.*;
import com.rt.schedulebase.entity.*;
import com.rt.schedulebase.mapper.*;
import com.rt.schedulenew.api.IDictSerialService;
import com.rt.schedulenew.api.*;
import com.rt.schedulenew.utils.base.BigDecimalUtil;
import com.rt.schedulenew.utils.base.CommonUtil;
import com.rt.schedulenew.utils.base.ConstantsUtil;
import com.rt.schedulenew.utils.global.BusinessException;
import com.rt.schedulenew.utils.global.ErrorCode;
import com.rt.schedulenew.utils.global.JsonResult;
import com.rt.schedulenew.utils.global.JsonResultUtil;
import com.rt.schedulenew.utils.util.DateUtil;
import com.rt.schedulenew.utils.util.EhCacheUtil;
import com.rt.schedulenew.utils.util.MarshallerUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SourceServiceImpl implements ISourceService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    DictScheduleApmMapper dictScheduleApmMapper;
    @Autowired
    ExamScheduleApmMapper examScheduleApmMapper;
    @Autowired
    DictScheduleApmRegularMapper dictScheduleApmRegularMapper;
    @Autowired
    DictScheduleRegularDefMapper dictScheduleRegularDefMapper;
    @Autowired
    ICommonService commonServiceImpl;
    @Autowired
    IConfigService configServiceImpl;
    @Autowired
    MarshallerUtils marshallerUtils;
    @Autowired
    DictExamQueueMapper dictExamQueueMapper;
    @Autowired
    private IExamSyslogService examSyslogService;
    @Autowired
    private ExamScheduleMapper examScheduleMapper;
    @Autowired
    private DictScheduleApmServiceImpl dictScheduleApmService;
    @Autowired
    private IDictScheduleApmRegularService dictScheduleApmRegularService;
    @Autowired
    private IDictScheduleRegularDefService dictScheduleRegularDefService;
    @Autowired
    private IDictCommonUseService dictCommonUseService;
    @Autowired
    private IDictSerialService dictSerialService;
    @Autowired
    private DictExamQueueServiceImpl dictExamQueueServiceImpl;
    @Autowired
    private IExamScheduleService examScheduleService;
    private static String SCHEDULE_APM = "schedule_apm";
    private static String Regular_Type = "0";
    private static String DATE_REGULAR = "日期";
    private static String WEEK_REGULAR = "星期";
    private static String COMMON_REGULAR = "通用";
    private static String NOT_REGULAR = "无号源";

    @Override
    public List<DictScheduleApmDto> getSourceList(DictScheduleApmDto dto) {
        List<DictScheduleApmDto> ampList = new ArrayList<>();
        if (!isCycleRange(dto)) {
            return ampList;
        }
        // 通用时段
        List<DictScheduleApmDto> commRList = dictScheduleApmMapper.getExamQueueApm(dto);
        // 查询是否选中周号
        String weekDate = dto.getWeekDate();
        String scheduleDate = dto.getScheduleDate();
        if (StringUtils.isBlank(scheduleDate) && StringUtils.isBlank(weekDate)) {
            for (DictScheduleApmDto apm : commRList) {
                apm.setScheduleApmScope(commonServiceImpl.getScheduleApmScope(apm.getTimeStart(), apm.getTimeEnd()));
            }
            getRegularDef(commRList);
            return commRList;
        }
        if (StringUtils.isNotBlank(scheduleDate)) {
            weekDate = DateUtil.getNumberWeek(DateUtil.parse(scheduleDate, DateUtil.FORMAT_DATE));
            dto.setWeekDate(weekDate);
        }
        if (CollectionUtils.isNotEmpty(commRList)) {
            for (DictScheduleApmDto dictScheduleApmDto : commRList) {
                List<DictScheduleApmDto> examQueueList = new ArrayList<>();
                dto.setScheduleApm(dictScheduleApmDto.getScheduleApm());
                dto.setTimeStart(dictScheduleApmDto.getTimeStart());
                dto.setTimeEnd(dictScheduleApmDto.getTimeEnd());
                if (StringUtils.isNotBlank(scheduleDate)) {
                    examQueueList = dictScheduleApmMapper.getOneDateExamQueueApm(dto);
                }
                boolean isEntry = false;
                if (CollectionUtils.isNotEmpty(examQueueList)) {
                    ampList.addAll(examQueueList);
                    isEntry = true;
                }
                if (!isEntry) {
                    examQueueList = dictScheduleApmMapper.getOneWeekExamQueueApm(dto);
                    if (CollectionUtils.isNotEmpty(examQueueList)) {
                        ampList.addAll(examQueueList);
                        isEntry = true;
                    }
                }
                if (!isEntry) {
                    ampList.add(dictScheduleApmDto);
                }
            }
        }

        // 获取只有日期号源的，放射科数据
        if (CollectionUtils.isEmpty(commRList) && StringUtils.isNotBlank(scheduleDate)) {
            dto.setWeekDate(null);
            commRList = dictScheduleApmMapper.getDateScheduleApm(dto);
            if (CollectionUtils.isNotEmpty(commRList)) {
                commRList.forEach(x -> x.setResourceMark("日期"));
            }
            ampList.addAll(commRList);
            // getRegularDef(commRList);
        }
        for (DictScheduleApmDto apm : ampList) {
            apm.setScheduleApmScope(commonServiceImpl.getScheduleApmScope(apm.getTimeStart(), apm.getTimeEnd()));
        }
        getRegularDef(ampList);

        // 重新计算启用状态
        if (CollectionUtils.isNotEmpty(commRList)) {
            commRList.forEach(x -> {
                if (x.getStopFlag().equals("0") && x.getUseStatus().equals("t")) {
                    x.setStopFlag("0");
                } else {
                    x.setStopFlag("1");
                }
            });
        }
        return ampList;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult manyStartOrStopSource(DictScheduleApmDto dto) {
        List<String> timeStartList = CommonUtil.split2List(dto.getTimeStart());
        DictScheduleApmDto apm = new DictScheduleApmDto();
        apm.setQueueName(dto.getQueueName());
        apm.setTimeStarts(timeStartList);
        apm.setDateStart(dto.getDateStart());
        apm.setDateEnd(dto.getDateEnd());
        List<DictScheduleApmDto> commonList = dictScheduleApmMapper.getCommonScheduleApm(apm);
        if (CollectionUtils.isEmpty(commonList)) {
            return JsonResultUtil.failure("启用（停用）未查询到号源");
        }
        String[] dateArr = dto.getScheduleDate().split(",");
        if (dto.getResourceMark().equals(WEEK_REGULAR)) {
            dateArr = dto.getWeekDate().split(",");
        }
        if (dateArr.length == 0) {
            return JsonResultUtil.failure("请选择需要批量修改的日期");
        }
        for (String date : dateArr) {
            List<DictScheduleApmDto> dateList = new ArrayList<>();
            if (dto.getResourceMark().equals(DATE_REGULAR)) {
                apm.setScheduleDate(date);
                dateList = dictScheduleApmMapper.getDateScheduleApm(apm);
            } else if (dto.getResourceMark().equals(WEEK_REGULAR)) {
                apm.setWeekDate(date);
                dateList = dictScheduleApmMapper.getWeekScheduleApm(apm);
            }
            DictScheduleApmDto dsa = new DictScheduleApmDto();
            dsa.setExamClass(dto.getExamClass());
            dsa.setQueueName(dto.getQueueName());
            dsa.setScheduleDate(date);
            dsa.setStopFlag(dto.getStopFlag());
            List<String> dataTimeStar = new ArrayList<String>();
            if (dateList != null && dateList.size() > 0) {
                for (DictScheduleApmDto list : dateList) {
                    if ("2".equals(list.getStopFlag())) {
                        continue;
                    }
                    dataTimeStar.add(list.getTimeStart());
                }
            }
            for (DictScheduleApmDto list : commonList) {
                StringBuffer sb = new StringBuffer();
                if (!dataTimeStar.contains(list.getTimeStart())) {
                    sb.append(",通用=" + list.getScheduleApm() + "=" + list.getDateStart() + "=" + list.getDateEnd());
                } else {
                    sb.append(",日期=" + list.getScheduleApm() + "=" + date + "=" + list.getDateStart() + "=" + list.getDateEnd());
                }
                dsa.setQueueScheduleApm(sb.substring(1));
                startOrStopForSource(dsa);
            }
        }
        return JsonResultUtil.success("成功");
    }

    @Override
    public String startOrStopForSource(DictScheduleApmDto dto) {
        removeSourceCache();
        String stopFlag = dto.getStopFlag();
        String weekDate = dto.getWeekDate();
        String scheduleDate = dto.getScheduleDate();
        String[] queueNameApms = dto.getQueueScheduleApm().split(",");
        StringBuffer apmCodes = new StringBuffer();
        for (String queueNameApm : queueNameApms) {
            if (StringUtils.isNotBlank(scheduleDate)) {
                dto.setWeekDate("");
            }
            DictScheduleApmDto apmDto = new DictScheduleApmDto();
            Map<String, Object> map = new HashMap<String, Object>();
            String[] queueNameApmArr = queueNameApm.split("=");
            String tableName = queueNameApmArr[0];
            apmDto.setQueueName(dto.getQueueName());
            apmDto.setScheduleApm(queueNameApmArr[1]);
            map.put("QUEUE_NAME", dto.getQueueName());
            map.put("SCHEDULE_APM", queueNameApmArr[1]);
            int indexStart = 3;
            int indexEnd = 4;
            if (tableName.equals(COMMON_REGULAR)) {
                indexStart = 2;
                indexEnd = 3;
            }
            String dateStart = queueNameApmArr[indexStart];
            String dateEnd = queueNameApmArr[indexEnd];
            apmDto.setDateStart(dateStart);
            apmDto.setDateEnd(dateEnd);
            map.put("DATE_START", dateStart);
            map.put("DATE_END", dateEnd);
            String operateName = Regular_Type.equals(stopFlag) ? ConstantsUtil.OperateName.OPEN.getDesc() : ConstantsUtil.OperateName.STOP.getDesc();
            String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_COMMON.name();
            apmDto.setExamClass(dto.getExamClass());
            apmDto.setResourceMark(tableName);
            apmDto.setStopFlag(stopFlag);
            if (tableName.equals(COMMON_REGULAR) || (tableName.equals(WEEK_REGULAR) && StringUtils.isBlank(weekDate))) {
                if (StringUtils.isBlank(scheduleDate) && StringUtils.isBlank(weekDate)) {
                    updateCommonForStopFlag(map, stopFlag);
                    examSyslogService.saveExamSyslogForDesc(moduleName, operateName, apmDto);
                } else {
                    dto.setScheduleApm(queueNameApmArr[1]);
                    if (tableName.equals(WEEK_REGULAR)) {
                        dto.setWeekDate(queueNameApmArr[2]);
                    }
                    dto.setDateStart(dateStart);
                    dto.setDateEnd(dateEnd);
                    String apmCode = addDictScheduleApm(dto, tableName);
                    apmCodes.append("," + apmCode);
                }
                dto.setResourceMark(tableName);
            } else {
                if (tableName.equals(DATE_REGULAR)) {
                    apmDto.setScheduleDate(queueNameApmArr[2]);
                    map.put("SCHEDULE_DATE", queueNameApmArr[2]);
                    moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
                } else {
                    apmDto.setWeekDate(queueNameApmArr[2]);
                    map.put("WEEK_DATE", queueNameApmArr[2]);
                    moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
                }
                updateDateOrWeekForStopFlag(map, stopFlag);
                dto.setResourceMark(tableName);
                examSyslogService.saveExamSyslogForDesc(moduleName, operateName, apmDto);
            }
        }
        if (StringUtils.isNotBlank(apmCodes)) {
            dto.setApmCode(apmCodes.substring(1));
        }
        return "成功";
    }

    private List<DictScheduleApm> queryDictScheduleApm(DictScheduleApmDto dto, String tableName, boolean isScheduleApm) {
        QueryWrapper<DictScheduleApm> query = new QueryWrapper<>();
        query.eq("DATE_START", dto.getDateStart());
        query.eq("DATE_END", dto.getDateEnd());
        query.eq("QUEUE_NAME", dto.getQueueName());
        if (isScheduleApm) {
            query.eq("SCHEDULE_APM", dto.getScheduleApm());
        } else {
            query.eq("TIME_START", dto.getTimeStart());
            query.eq("TIME_END", dto.getTimeEnd());
        }
        if (tableName.equals(COMMON_REGULAR)) {
            query.isNull("SCHEDULE_DATE");
            query.isNull("WEEK_DATE");
        } else if (tableName.equals(DATE_REGULAR)) {
            query.eq("SCHEDULE_DATE", dto.getScheduleDate());
        } else {
            query.eq("WEEK_DATE", dto.getWeekDate());
        }
        return dictScheduleApmMapper.selectList(query);
    }

    private void updateFormat(UpdateWrapper<DictScheduleApm> update, DictScheduleApmDto apm) {
        update.set(StringUtils.isBlank(apm.getTimeScheduleLatest()), "TIME_SCHEDULE_LATEST", "");
        update.set(StringUtils.isBlank(apm.getTimeEarliest()), "TIME_EARLIEST", "");
        update.set(StringUtils.isBlank(apm.getDrugTime()), "DRUG_TIME", "");
        update.set(StringUtils.isBlank(apm.getNotice()), "NOTICE", "");
        update.set(Objects.isNull(apm.getDaysEarliest()), "DAYS_EARLIEST", "");
        update.set(Objects.isNull(apm.getDaysScheduleLatest()), "DAYS_SCHEDULE_LATEST", "");
        update.set(Objects.isNull(apm.getTimeScheduleFirst()), "TIME_SCHEDULE_FIRST", "");
        update.set(Objects.isNull(apm.getDaysScheduleFirst()), "DAYS_SCHEDULE_FIRST", "");
    }

    @Override
    public String addDictScheduleApm(DictScheduleApmDto dto, String tableName) {
        String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
        if (StringUtils.isNotBlank(dto.getWeekDate())) {
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
        }
        DictScheduleApmDto apmDto = new DictScheduleApmDto();
        List<DictScheduleApm> list = queryDictScheduleApm(dto, tableName, true);
        if (list != null && list.size() > 0) {
            DictScheduleApm apm = list.get(0);
            String oldApmCode = apm.getApmCode();
            apm.setStopFlag(dto.getStopFlag());
            apm.setScheduleDate(dto.getScheduleDate());
            apm.setWeekDate(dto.getWeekDate());
            if (tableName.equals(WEEK_REGULAR)) {
                apm.setWeekDate("");
            }
            String regularName = StringUtils.isNotBlank(apm.getWeekDate()) ? WEEK_REGULAR : DATE_REGULAR;
            dto.setTimeStart(apm.getTimeStart());
            dto.setTimeEnd(apm.getTimeEnd());
            List<DictScheduleApm> oldDateList = queryDictScheduleApm(dto, regularName, false);
            boolean isOldDateList = oldDateList != null && oldDateList.size() > 0;
            String apmCode = "";
            boolean isRepeat = false;
            if (isOldDateList) {
                apmCode = oldDateList.get(0).getApmCode();
                UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
                update.eq("APM_CODE", apmCode);
                apm.setApmCode(apmCode);
                BeanUtils.copyProperties(apm, apmDto);
                updateFormat(update, apmDto);
                dictScheduleApmMapper.update(entity(apmDto), update);
            } else {
                BeanUtils.copyProperties(apm, apmDto);
                isRepeat = isRepeatData(apmDto);
                if (!isRepeat) {
                    apmCode = dictSerialService.getSerialId("APM_CODE");
                    apmDto.setApmCode(apmCode);
                    dictScheduleApmMapper.insert(entity(apmDto));
                }
            }
            if (!isRepeat) {
                copyDictScheduleApmRegular(oldApmCode, apmCode, apmDto);
            }
        }
        tableName = (StringUtils.isBlank(dto.getScheduleDate()) ? WEEK_REGULAR : DATE_REGULAR);
        apmDto.setExamClass(dto.getExamClass());
        apmDto.setResourceMark(tableName);
        examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.INSERT.getDesc(), apmDto);
        return apmDto.getApmCode();
    }

    private boolean isRepeatData(DictScheduleApmDto apmDto) {
        boolean isRepeat = false;
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("QUEUE_NAME", apmDto.getQueueName());
        map.put("SCHEDULE_DATE", apmDto.getScheduleDate());
        map.put("WEEK_DATE", apmDto.getWeekDate());
        map.put("DATE_START", apmDto.getDateStart());
        map.put("DATE_END", apmDto.getDateEnd());
        map.put("TIME_START", apmDto.getTimeStart());
        map.put("TIME_END", apmDto.getTimeEnd());
        QueryWrapper<DictScheduleApm> qw = new QueryWrapper<>();
        qw.allEq(map, false);
        int i = dictScheduleApmMapper.selectCount(qw);
        if (i > 0) {
            isRepeat = true;
        }
        return isRepeat;
    }

    private void copyDictScheduleApmRegular(String oldApmCode, String apmCode, DictScheduleApmDto apmDto) {
        QueryWrapper<DictScheduleApmRegular> regularQuery = new QueryWrapper<>();
        regularQuery.eq("APM_CODE", oldApmCode);
        List<DictScheduleApmRegular> regList = dictScheduleApmRegularMapper.selectList(regularQuery);
        QueryWrapper<DictScheduleApmRegular> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("APM_CODE", apmCode);
        dictScheduleApmRegularMapper.delete(queryWrapper);
        StringBuffer bf = new StringBuffer();
        if (regList != null && regList.size() > 0) {
            for (int i = 0; i < regList.size(); ++i) {
                DictScheduleApmRegular regular = regList.get(i);
                bf.append("," + regular.getRegularId());
                regular.setApmCode(apmCode);
                dictScheduleApmRegularMapper.insert(regular);
            }
            apmDto.setRegularDefSchedule(bf.substring(1));
        }
    }

    /**
     * 取消特殊号源
     * 日期号源 -> 通用
     * 周号源 -> 通用
     * 日期号源 -> 周号源
     *
     * @param dto
     * @return
     */
    @Override
    public String cancelModify(DictScheduleApmDto dto) {
        removeSourceCache();
        String[] split = dto.getQueueScheduleApm().split(",");
        for (String queueApm : split) {
            // [取消类型][apmcode][日期或者周几]
            String[] queueApmArr = queueApm.split("=");
            String apmCode = queueApmArr[1];
            // 星期、日期
            String resourceMark = queueApmArr[0];
            if (dto.getResourceMark().equals(resourceMark)) {
                String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
                // 日期号源
                if (resourceMark.equals(DATE_REGULAR)) {
                    dto.setScheduleDate(queueApmArr[2]);
                } else if (resourceMark.equals(WEEK_REGULAR)) {
                    // 星期号源
                    dto.setWeekDate(queueApmArr[2]);
                    moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
                }
                if (StringUtils.isNotBlank(apmCode)) {
                    dto.setResourceMark(resourceMark);
                    dto.setApmCode(apmCode);

                    // 停止特殊号源
                    UpdateWrapper<DictScheduleApm> up = new UpdateWrapper<>();
                    up.eq("APM_CODE", apmCode);
                    up.set("STOP_FLAG", "2");
                    dictScheduleApmMapper.update(null, up);

                    QueryWrapper<DictScheduleApm> apmQueryWrapper = new QueryWrapper<>();
                    apmQueryWrapper.eq("APM_CODE", apmCode);
                    DictScheduleApm scheduleApm = dictScheduleApmMapper.selectOne(apmQueryWrapper);

                    if (Objects.nonNull(scheduleApm)) {
                        // 将特殊号源已预约的数量挪到对应号源(周或者通用)
                        if (resourceMark.equals(DATE_REGULAR)) {
                            // 查询时段的预约数量
                            QueryWrapper<ExamScheduleApm> examScheduleApmQueryWrapper = new QueryWrapper<>();
                            examScheduleApmQueryWrapper.eq("APM_CODE", apmCode);
                            examScheduleApmQueryWrapper.eq("SCHEDULE_DATE", queueApmArr[2]);
                            // queueApmArr[2] 可能是日期也可能是周几数字

                            ExamScheduleApm oldScheduleApm = examScheduleApmMapper.selectOne(examScheduleApmQueryWrapper);
                            // 日期特殊号源有被用的情况也要占用 通用号源的数量
                            if (Objects.nonNull(oldScheduleApm)) {
                                // 日期号源 可能降级成周号源或者通用号源
                                String weekDay = String.valueOf(DateUtil.getWeekDay(scheduleApm.getScheduleDate()));
                                apmQueryWrapper = new QueryWrapper<>();
                                apmQueryWrapper.eq("QUEUE_NAME", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("DATE_START", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("DATE_END", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("TIME_START", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("TIME_END", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("STOP_FLAG", "0");
                                apmQueryWrapper.eq("WEEK_DATE", weekDay);
                                apmQueryWrapper.isNull("SCHEDULE_DATE");

                                DictScheduleApm weekApm = dictScheduleApmMapper.selectOne(apmQueryWrapper);
                                if (Objects.nonNull(weekApm)) {
                                    // 查询周时段的预约数量
                                    examScheduleApmQueryWrapper = new QueryWrapper<>();
                                    examScheduleApmQueryWrapper.eq("APM_CODE", weekApm.getApmCode());
                                    examScheduleApmQueryWrapper.eq("SCHEDULE_DATE", scheduleApm.getScheduleDate());
                                    ExamScheduleApm weekScheduleApm = examScheduleApmMapper.selectOne(examScheduleApmQueryWrapper);
                                    if (Objects.isNull(weekScheduleApm)) {
                                        // 直接修改 oldScheduleApm,将 日期号源的apmcode换成周号源的apmcode
                                        UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                        updateWrapper.set("APM_CODE", weekApm.getApmCode());
                                        updateWrapper.eq("APM_CODE", oldScheduleApm.getApmCode());
                                        updateWrapper.eq("SCHEDULE_DATE", oldScheduleApm.getScheduleDate());
                                        examScheduleApmMapper.update(null, updateWrapper);
                                    } else {
                                        // 不为空就要修改 周号源被占用的数量
                                        UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                        updateWrapper.set("COUNT", oldScheduleApm.getCount());
                                        updateWrapper.set("COUNT_RECYCLE", oldScheduleApm.getCountRecycle());
                                        updateWrapper.set("ORGANS_RECYCLE", oldScheduleApm.getOrgansRecycle());

                                        updateWrapper.eq("APM_CODE", weekScheduleApm.getApmCode());
                                        updateWrapper.eq("SCHEDULE_DATE", weekScheduleApm.getScheduleDate());
                                        examScheduleApmMapper.update(null, updateWrapper);
                                    }
                                } else {
                                    // 没有周号源就找通用号源
                                    apmQueryWrapper = new QueryWrapper<>();
                                    apmQueryWrapper.eq("QUEUE_NAME", scheduleApm.getQueueName());
                                    apmQueryWrapper.eq("DATE_START", scheduleApm.getQueueName());
                                    apmQueryWrapper.eq("DATE_END", scheduleApm.getQueueName());
                                    apmQueryWrapper.eq("TIME_START", scheduleApm.getQueueName());
                                    apmQueryWrapper.eq("TIME_END", scheduleApm.getQueueName());
                                    apmQueryWrapper.eq("STOP_FLAG", "0");
                                    apmQueryWrapper.isNull("WEEK_DATE");
                                    apmQueryWrapper.isNull("SCHEDULE_DATE");

                                    DictScheduleApm commonApm = dictScheduleApmMapper.selectOne(apmQueryWrapper);
                                    if (Objects.nonNull(commonApm)) {
                                        // 查询通用时段的预约数量
                                        examScheduleApmQueryWrapper = new QueryWrapper<>();
                                        examScheduleApmQueryWrapper.eq("APM_CODE", commonApm.getApmCode());
                                        examScheduleApmQueryWrapper.eq("SCHEDULE_DATE", scheduleApm.getScheduleDate());
                                        ExamScheduleApm commonScheduleApm = examScheduleApmMapper.selectOne(examScheduleApmQueryWrapper);
                                        if (Objects.isNull(commonScheduleApm)) {
                                            // 直接修改 oldScheduleApm,将 日期号源的apmcode换成通用号源的apmcode
                                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                            updateWrapper.set("APM_CODE", commonApm.getApmCode());
                                            updateWrapper.eq("APM_CODE", oldScheduleApm.getApmCode());
                                            updateWrapper.eq("SCHEDULE_DATE", oldScheduleApm.getScheduleDate());
                                            examScheduleApmMapper.update(null, updateWrapper);
                                        } else {
                                            // 不为空就要修改 通用号源被占用的数量
                                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                            updateWrapper.set("COUNT", oldScheduleApm.getCount());
                                            updateWrapper.set("COUNT_RECYCLE", oldScheduleApm.getCountRecycle());
                                            updateWrapper.set("ORGANS_RECYCLE", oldScheduleApm.getOrgansRecycle());

                                            updateWrapper.eq("APM_CODE", commonScheduleApm.getApmCode());
                                            updateWrapper.eq("SCHEDULE_DATE", commonScheduleApm.getScheduleDate());
                                            examScheduleApmMapper.update(null, updateWrapper);
                                        }
                                    }
                                }
                            }
                        } else if (resourceMark.equals(WEEK_REGULAR)) {
                            // 星期号源
                            // 获取星期号源被预约的数量
                            QueryWrapper<ExamScheduleApm> examScheduleApmQueryWrapper = new QueryWrapper<>();
                            examScheduleApmQueryWrapper.eq("APM_CODE", apmCode);
                            examScheduleApmQueryWrapper.ge("SCHEDULE_DATE", DateUtil.getCurrentDate());

                            List<ExamScheduleApm> oldScheduleApms = examScheduleApmMapper.selectList(examScheduleApmQueryWrapper);
                            // 日期号源有被用的情况也要占用 通用号源的数量
                            if (CollectionUtils.isNotEmpty(oldScheduleApms)) {
                                apmQueryWrapper = new QueryWrapper<>();
                                apmQueryWrapper.eq("QUEUE_NAME", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("DATE_START", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("DATE_END", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("TIME_START", scheduleApm.getQueueName());
                                apmQueryWrapper.eq("TIME_END", scheduleApm.getQueueName());
                                 apmQueryWrapper.eq("STOP_FLAG", "0");
                                apmQueryWrapper.isNull("WEEK_DATE");
                                apmQueryWrapper.isNull("SCHEDULE_DATE");
                                DictScheduleApm commonApm = dictScheduleApmMapper.selectOne(apmQueryWrapper);
                                if (Objects.nonNull(commonApm)) {
                                    List<String> scheduelDates = oldScheduleApms.stream()
                                            .map(x -> x.getScheduleDate()).collect(Collectors.toList());
                                    // 查询通用时段的预约数量
                                    examScheduleApmQueryWrapper = new QueryWrapper<>();
                                    examScheduleApmQueryWrapper.eq("APM_CODE", commonApm.getApmCode());
                                    examScheduleApmQueryWrapper.in("SCHEDULE_DATE", scheduelDates);

                                    List<ExamScheduleApm> commonScheduleApms = examScheduleApmMapper.selectList(examScheduleApmQueryWrapper);
                                    for (ExamScheduleApm oldScheduleApm : oldScheduleApms) {
                                        ExamScheduleApm commonScheduleApm = commonScheduleApms.stream().filter(x -> x.getScheduleDate().equals(oldScheduleApm.getScheduleDate()))
                                                .findFirst().orElse(null);
                                        if (commonScheduleApm == null) {
                                            // 直接修改 oldScheduleApm,将 日期号源的apmcode换成通用号源的apmcode
                                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                            updateWrapper.set("APM_CODE", commonApm.getApmCode());
                                            updateWrapper.eq("APM_CODE", oldScheduleApm.getApmCode());
                                            updateWrapper.eq("SCHEDULE_DATE", oldScheduleApm.getScheduleDate());
                                            examScheduleApmMapper.update(null, updateWrapper);
                                        } else {
                                            // 不为空就要修改 通用号源被占用的数量
                                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                                            updateWrapper.set("COUNT", oldScheduleApm.getCount());
                                            updateWrapper.set("COUNT_RECYCLE", oldScheduleApm.getCountRecycle());
                                            updateWrapper.set("ORGANS_RECYCLE", oldScheduleApm.getOrgansRecycle());

                                            updateWrapper.eq("APM_CODE", commonScheduleApm.getApmCode());
                                            updateWrapper.eq("SCHEDULE_DATE", commonScheduleApm.getScheduleDate());
                                            examScheduleApmMapper.update(null, updateWrapper);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.DELETE.getDesc(), dto);
                    // 解除特殊号源的预约规则绑定
                    QueryWrapper<DictScheduleApmRegular> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("APM_CODE", apmCode);
                    dictScheduleApmRegularMapper.delete(queryWrapper);
                }
            }
        }
        return "成功";
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult saveScheduleApm(DictScheduleApmDto dto) {
        String result = checkScheduleQueueApm(dto);
        if (StringUtils.isNotBlank(result)) {
            return JsonResultUtil.failure(result);
        }
        if (dto.getDateStart().length() < 5 || dto.getDateEnd().length() < 5) {
            return JsonResultUtil.failure("周期日期有误");
        }
        if (StringUtils.isBlank(dto.getDateStart()) || StringUtils.isBlank(dto.getDateEnd())) {
            return JsonResultUtil.failure("周期入参错误");
        }
        // 计算时间段是否重叠
        String msg = judgeOverlap(dto, true);
        if (!"ok".equals(msg)) {
            return JsonResultUtil.failure(msg);
        }
        saveScheduleApmOrRegular(dto);
        removeSourceCache();
        return JsonResultUtil.success("成功");
    }

    /***
     * 修改号源时段设置
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult editScheduleApm(DictScheduleApmDto dto) {
        // 参数检查 时段名不能为空
        String result = checkScheduleQueueApm(dto);

        if (StringUtils.isNotBlank(result)) {
            return JsonResultUtil.failure(result);
        }
        // 清理缓存
        removeSourceCache();
        // 修改通用号源
        if (StringUtils.isBlank(dto.getScheduleDate()) && StringUtils.isBlank(dto.getWeekDate())) {
            updateScheduleApmInfo(dto);
            return JsonResultUtil.success("成功");
        }
        // 修改特殊号源
        // 是否存在,存在更新，不存在新增
        boolean isUpdate = hasExist(dto);
        if (isUpdate) {
            updateScheduleApmInfo(dto);
        } else {
            // 新增一个时段
            String msg = judgeOverlap(dto, true);
            if (!"ok".equals(msg)) {
                return JsonResultUtil.failure(msg);
            }
            saveScheduleApmOrRegular(dto);
        }
        return JsonResultUtil.success("成功");
    }

    /***
     * 检查检查队列时段名称参数
     * @param dto
     * @return
     */
    private String checkScheduleQueueApm(DictScheduleApmDto dto) {
        if (StringUtils.isBlank(dto.getScheduleApm())) {
            return "时段名不能为空!";
        }
        if (dto.getScheduleApm().length() > 16) {
            return "时段名称长度超过限制(16)!";
        }
        return null;
    }

    private String updateExamSyslog(DictScheduleApmDto dto, String operateName) {
        String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_COMMON.name();
        dto.setResourceMark(COMMON_REGULAR);
        if (StringUtils.isNotBlank(dto.getScheduleDate())) {
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
            dto.setResourceMark(DATE_REGULAR);
        } else if (StringUtils.isNotBlank(dto.getWeekDate())) {
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
            dto.setResourceMark(WEEK_REGULAR);
        }
        examSyslogService.saveExamSyslogForDesc(moduleName, operateName, dto);
        return moduleName;
    }

    private void updateScheduleApmInfo(DictScheduleApmDto dto) {
        UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
        update.eq("APM_CODE", dto.getApmCode());
        // 计算时间段是否重叠
        judgeOverlap(dto, false);

        updateFormat(update, dto);
        //
        updateExamSyslog(dto, ConstantsUtil.OperateName.UPDATE.getDesc());
        if (!dto.getScheduleApm().equals(dto.getOldScheduleApm())) {
            ExamSchedule es = new ExamSchedule();
            es.setScheduleApm(dto.getScheduleApm());
            UpdateWrapper<ExamSchedule> esup = new UpdateWrapper<>();
            esup.eq("APM_CODE", dto.getApmCode());
            examScheduleMapper.update(es, esup);
        }
        dictScheduleApmMapper.update(entity(dto), update);
        saveOrUpdateScheduleApmRegular(dto);
    }

    public DictScheduleApmDto getLastScheduleInfo(DictScheduleApmDto dto) {
        DictScheduleApm dsa = dictScheduleApmService.selectOneByApmCode(dto.getApmCode());
        BeanUtils.copyProperties(dsa, dto);
        String limitType = commonServiceImpl.getLimitType(dto.getExamClass());
        dto.setLimitType(limitType);
        DictScheduleApmRegularDto dsar = new DictScheduleApmRegularDto();
        dsar.setApmCode(dto.getApmCode());
        List<String> types = Arrays.asList("0,3".split(","));
        dsar.setRegularTypes(types);
        List<DictScheduleApmRegularDto> regularDefScheduleList = dictScheduleApmRegularMapper.getRegularDefInfo(dsar);
        List<String> defName = new ArrayList<>();
        StringBuffer def = new StringBuffer();
        List<String> name = new ArrayList<>();
        StringBuffer sb = new StringBuffer();
        if (regularDefScheduleList != null && regularDefScheduleList.size() > 0) {
            for (DictScheduleApmRegularDto regularDefSchedule : regularDefScheduleList) {
                if ("0".equals(regularDefSchedule.getRegularType())) {
                    defName.add(regularDefSchedule.getRegularName());
                    def.append("," + regularDefSchedule.getRegularName());
                } else {
                    if (!"3".equals(regularDefSchedule.getRegularType())) {
                        continue;
                    }
                    name.add(regularDefSchedule.getRegularName() + "[" + regularDefSchedule.getMaxLimit() + "]");
                    sb.append("," + regularDefSchedule.getRegularName() + "[" + regularDefSchedule.getMaxLimit() + "]");
                }
            }
            dto.setRegularScheduleNameList(name);
            dto.setRegularDefScheduleNameList(defName);
            if (StringUtils.isNotBlank(def)) {
                dto.setRegularDefScheduleName(def.substring(1));
            }
            if (StringUtils.isNotBlank(sb)) {
                dto.setRegularScheduleName(sb.substring(1));
            }
        }
        return dto;
    }

    @Override
    public JsonResult updateScheduleApmMaxLimit(DictScheduleApmDto dto) {
        removeSourceCache();
        boolean isUpdate = (WEEK_REGULAR.equals(dto.getResourceMark()) && StringUtils.isNotBlank(dto.getWeekDate()))
                || (DATE_REGULAR.equals(dto.getResourceMark()) && StringUtils.isNotBlank(dto.getScheduleDate()))
                || (COMMON_REGULAR.equals(dto.getResourceMark()) && StringUtils.isBlank(dto.getScheduleDate()) && StringUtils.isBlank(dto.getWeekDate()));
        DictScheduleApm apm = new DictScheduleApm();
        apm.setMaxLimit(dto.getMaxLimit());
        apm.setStopFlag(dto.getStopFlag());
        UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
        DictScheduleApmDto apmDto = new DictScheduleApmDto();
        apmDto.setApmCode(dto.getApmCode());
        apmDto.setExamClass(dto.getExamClass());
        getLastScheduleInfo(apmDto);
        boolean isEq = dto.getMaxLimit().equals(apmDto.getMaxLimit());
        apmDto.setMaxLimit(dto.getMaxLimit());
        apmDto.setResourceMark(dto.getResourceMark());
        if (isUpdate) {
            if (isEq) {
                return JsonResultUtil.success("成功");
            }
            updateExamSyslog(apmDto, ConstantsUtil.OperateName.UPDATE.getDesc());
            update.eq("APM_CODE", dto.getApmCode());
            dictScheduleApmMapper.update(apm, update);
        } else {
            apmDto.setScheduleDate(dto.getScheduleDate());
            apmDto.setWeekDate(dto.getWeekDate());
            String tableName = StringUtils.isBlank(dto.getScheduleDate()) ? WEEK_REGULAR : DATE_REGULAR;
            List<DictScheduleApm> list = queryDictScheduleApm(apmDto, tableName, false);
            boolean isList = list != null && list.size() > 0;
            String apmCode = "";
            boolean isRepeat = false;
            String stopFlag = dto.getStopFlag();
            if (StringUtils.isBlank(stopFlag)) {
                stopFlag = apmDto.getStopFlag();
            }
            if (isList) {
                apmCode = list.get(0).getApmCode();
                update.eq("APM_CODE", apmCode);
                apm.setStopFlag(stopFlag);
                dictScheduleApmMapper.update(apm, update);
                apmDto.setApmCode(apmCode);
            } else {
                isRepeat = isRepeatData(apmDto);
                if (!isRepeat) {
                    apmCode = dictSerialService.getSerialId("APM_CODE");
                    apmDto.setApmCode(apmCode);
                    apmDto.setStopFlag(stopFlag);
                    dictScheduleApmMapper.insert(entity(apmDto));
                }
            }
            if (!isRepeat) {
                copyDictScheduleApmRegular(dto.getApmCode(), apmCode, apmDto);
            }
            apmDto.setResourceMark(tableName);
            updateExamSyslog(apmDto, ConstantsUtil.OperateName.INSERT.getDesc());
        }
        return JsonResultUtil.success("成功");
    }

    /**
     * 新增号源时段
     *
     * @param dto
     */
    private void saveScheduleApmOrRegular(DictScheduleApmDto dto) {
        boolean isList = false;
        String tableName = COMMON_REGULAR;
        // 新增通用时段
        if (StringUtils.isBlank(dto.getScheduleDate()) && StringUtils.isBlank(dto.getWeekDate())) {
            dto.setOldApmCode(dto.getApmCode());
            dto.setApmCode(dictSerialService.getSerialId("APM_CODE"));
        } else {
            // 新增 日期或者周号源时段
            tableName = WEEK_REGULAR;
            if (StringUtils.isNotBlank(dto.getScheduleDate())) {
                tableName = DATE_REGULAR;
                dto.setWeekDate("");
            }
            // 查询是否已存在特殊的时段号源
            List<DictScheduleApm> list = queryDictScheduleApm(dto, tableName, false);
            isList = CollectionUtils.isNotEmpty(list);
            if (isList) {
                dto.setOldApmCode(dto.getApmCode());
                // 如果存在就修改存在的时段编码的值
                dto.setApmCode(list.get(0).getApmCode());
            } else {
                dto.setOldApmCode(dto.getApmCode());
                // 不存在就新生成一个时段编码
                dto.setApmCode(dictSerialService.getSerialId("APM_CODE"));
            }
        }
        updateExamSyslog(dto, ConstantsUtil.OperateName.INSERT.getDesc());
        // 将通用号源的已预约数量-修改到新增的特殊号源上面
        saveScheduleApmInfo(dto, isList);
        // 重新绑定 时段的预约规则和数量规则
        saveOrUpdateScheduleApmRegular(dto);
    }

    /**
     * 检查号源时段是否存在
     *
     * @param dto
     * @return true 存在 false 不存在
     */
    private boolean hasExist(DictScheduleApmDto dto) {
        QueryWrapper<DictScheduleApm> query = new QueryWrapper<>();
        query.eq("APM_CODE", dto.getApmCode());
        query.eq("QUEUE_NAME", dto.getQueueName());
        if (StringUtils.isNotBlank(dto.getScheduleDate())) {
            query.eq("SCHEDULE_DATE", dto.getScheduleDate());
        } else if (StringUtils.isNotBlank(dto.getWeekDate())) {
            query.eq("WEEK_DATE", dto.getWeekDate());
        }
        return dictScheduleApmMapper.selectCount(query) > 0;
    }

    private boolean cycleRangeJudge(DictScheduleApmDto dto) throws ParseException {
        QueryWrapper<DictScheduleApm> sa = new QueryWrapper<>();
        sa.eq("DATE_START", dto.getDateStart());
        sa.eq("DATE_END", dto.getDateEnd());
        sa.eq("QUEUE_NAME", dto.getQueueName());
        int count = dictScheduleApmMapper.selectCount(sa);
        if (count > 0) {
            return true;
        }
        boolean rangeType = dto.getDateStart().length() > 5;
        String currentYear = "";
        boolean currentIsPass = false;
        String currentDateStart = dto.getDateStart();
        String currentDateEnd = dto.getDateEnd();
        if (!rangeType) {
            currentIsPass = isNewYear(dto.getDateStart(), dto.getDateEnd());
            Calendar cale = Calendar.getInstance();
            currentYear = String.valueOf(cale.get(1));
            currentDateStart = currentYear + "-" + dto.getDateStart();
            currentDateEnd = currentYear + "-" + dto.getDateEnd();
            if (currentIsPass) {
                currentDateEnd = Integer.parseInt(currentYear) + 1 + "-" + dto.getDateEnd();
            }
        }
        List<DictScheduleApm> dsaList = new ArrayList<DictScheduleApm>();
        DictCommonUseDto dictCommonUseDto = new DictCommonUseDto();
        dictCommonUseDto.setValue("号源周期");
        dictCommonUseDto.setOldName(SCHEDULE_APM);
        dictCommonUseDto.setOldReserve1(dto.getQueueName());
        dictCommonUseDto.setOldExamClass(dto.getExamClass());
        DictCommonUse info = dictCommonUseService.getInfo(dictCommonUseDto);
        if (Objects.isNull(info)) {
            return true;
        }
        String reserve4 = info.getReserve4();
        if (StringUtils.isBlank(reserve4)) {
            return true;
        }
        List<String> colyceList = CommonUtil.split2List(reserve4);
        for (String colyce : colyceList) {
            DictScheduleApm scheduleApm = new DictScheduleApm();
            List<String> strings = CommonUtil.strToList(colyce, "~");
            scheduleApm.setDateStart(strings.get(0));
            scheduleApm.setDateEnd(strings.get(1));
            dsaList.add(scheduleApm);
        }
        Iterator<DictScheduleApm> iter = dsaList.iterator();
        while (iter.hasNext()) {
            DictScheduleApm dsa = iter.next();
            if (dto.getDateStart().length() != dsa.getDateStart().length()) {
                return false;
            }
            if (!dsa.getDateStart().equals(dto.getOldDateStart()) || !dsa.getDateEnd().equals(dto.getOldDateEnd())) {
                continue;
            }
            iter.remove();
        }
        if (rangeType) {
            Date inputBeginDate = DateUtil.parse(dto.getDateStart(), "yyyy-MM-dd");
            Date inputEndDate = DateUtil.parse(dto.getDateEnd(), "yyyy-MM-dd");
            for (DictScheduleApm item : dsaList) {
                Date beginDate = DateUtil.parse(item.getDateStart(), "yyyy-MM-dd");
                Date endDate = DateUtil.parse(item.getDateEnd(), "yyyy-MM-dd");
                if (!beginDate.before(inputBeginDate)) {
                    // 如果 开始时间 大于 提交的时间
                    if (!beginDate.after(inputEndDate)) {
                        return false;
                    }
                    if (!endDate.before(inputBeginDate)) {
                        return false;
                    }
                }
            }
            return true;
        }
        List<String> strList = new ArrayList<String>();
        Map<String, Object> map = new HashMap<String, Object>();
        for (DictScheduleApm dsa2 : dsaList) {
            boolean isPass = isNewYear(dsa2.getDateStart(), dsa2.getDateEnd());
            map.put(dsa2.getDateStart() + "~" + dsa2.getDateEnd(), isPass);
            String dateStart = currentYear + "-" + dsa2.getDateStart();
            String dateEnd = currentYear + "-" + dsa2.getDateEnd();
            if (isPass) {
                dateEnd = Integer.parseInt(currentYear) + 1 + "-" + dsa2.getDateEnd();
            }
            strList.addAll(getMonthBetween(dateStart, dateEnd, false));
        }
        List<String> currentStrList = getMonthBetween(currentDateStart, currentDateEnd, true);
        for (String currentStr : currentStrList) {
            if (strList.contains(currentStr)) {
                return false;
            }
        }
        for (Map.Entry<String, Object> obj : map.entrySet()) {
            String key = obj.getKey();
            boolean value = Boolean.parseBoolean(String.valueOf(obj.getValue()));
            if (currentIsPass && value) {
                return false;
            }
            String[] dateArr = key.split("~");
            if (currentIsPass) {
                if (!isNewYear(dto.getDateStart(), dateArr[1])) {
                    return false;
                }
                if (isNewYear(dto.getDateEnd(), dateArr[0]) || dto.getDateEnd().equals(dateArr[0])) {
                    return false;
                }
            } else if (!isNewYear(dto.getDateStart(), dateArr[1])) {
                if (isNewYear(dto.getDateEnd(), dateArr[0]) || dto.getDateEnd().equals(dateArr[0])) {
                    return false;
                }
            } else {
                if (value && (isNewYear(dto.getDateEnd(), dateArr[0]) || dto.getDateEnd().equals(dateArr[0]))) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 完善设置dto字段数据 计算时间段是否重叠
     *
     * @param dto
     * @param flag 是否判断时段是否重叠
     * @return ok 正常,其他： 错误
     */
    private String judgeOverlap(DictScheduleApmDto dto, boolean flag) {
        if (StringUtils.isBlank(dto.getScheduleApm())) {
            dto.setScheduleApm(dto.getScheduleApmScope());
        }
        String scheduleApmScope = dto.getScheduleApmScope();
        String[] scheduleApmArr = scheduleApmScope.split("~");
        String timeStart = scheduleApmArr[0];
        String timeEnd = scheduleApmArr[1];
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        try {
            Date date = df.parse(timeEnd + ":00");
            timeEnd = df.format(date.getTime() - 1000L);
            Date d1 = df.parse(timeStart + ":00");
            Date d2 = df.parse(scheduleApmArr[1] + ":00");
            // 时段间隔分钟数
            int apmLength = (int) ((d2.getTime() - d1.getTime()) / 60000L);
            dto.setApmLength(apmLength);
            timeStart = df.format(d1);
            dto.setLimitType(commonServiceImpl.getLimitType(dto.getExamClass()));
        } catch (ParseException e) {
            logger.error("judgeOverlap错误:", e);
        }
        dto.setTimeStart(timeStart);
        dto.setTimeEnd(timeEnd);
        // 是否判断时段是否重叠
        if (flag) {
            boolean isTimeRepeated = dictScheduleApmMapper.isTimeRepeated(dto) > 0;
            if (isTimeRepeated) {
                return "时段重叠，添加失败";
            }
        }
        if (StringUtils.isBlank(dto.getTimeSignin())) {
            dto.setTimeSignin(scheduleApmArr[1] + ":00");
        }
        dto.setOtherTimeSignin(scheduleApmArr[1] + ":00");
        return "ok";
    }

    public static List<String> getMonthBetween(String minDate, String maxDate, boolean isContain) throws ParseException {
        String[] minDateStr = minDate.split("-");
        minDate = minDateStr[0] + "-" + minDateStr[1];
        String[] maxDateStr = maxDate.split("-");
        maxDate = maxDateStr[0] + "-" + maxDateStr[1];
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(sdf.parse(minDate));
        min.set(min.get(1), min.get(2), 1);
        max.setTime(sdf.parse(maxDate));
        max.set(max.get(1), max.get(2), 2);
        Calendar curr = min;
        while (curr.before(max)) {
            String[] dateArr = sdf.format(curr.getTime()).split("-");
            if (isContain) {
                result.add(dateArr[1]);
            } else if (!minDate.equals(sdf.format(curr.getTime())) && !maxDate.equals(sdf.format(curr.getTime()))) {
                result.add(dateArr[1]);
            }
            curr.add(2, 1);
        }
        return result;
    }

    /**
     * 重新绑定 时段的预约规则和数量规则
     *
     * @param dto
     */
    private void saveOrUpdateScheduleApmRegular(DictScheduleApmDto dto) {
        // 删除预约规则绑定
        QueryWrapper<DictScheduleApmRegular> query = new QueryWrapper<>();
        query.eq("APM_CODE", dto.getApmCode());
        dictScheduleApmRegularMapper.delete(query);

        // 重新绑定预约规则和数量规则

        //预约规则
        String regularDefSchedule = dto.getRegularDefSchedule();
        if (StringUtils.isNotBlank(regularDefSchedule)) {
            String[] split = regularDefSchedule.split(",");
            for (String regularId : split) {
                DictScheduleApmRegular regular = new DictScheduleApmRegular();
                regular.setApmCode(dto.getApmCode());
                regular.setRegularId(regularId);
                dictScheduleApmRegularMapper.insert(regular);
            }
        }
        // 预约数量限制
        String regularSchedule = dto.getRegularSchedule();
        if (StringUtils.isNotBlank(regularSchedule)) {
            String[] regularArr = regularSchedule.split(",");
            for (String regulars : regularArr) {
                // 格式 0009=0-88=0
                String[] queueApmArr = regulars.split("=");
                DictScheduleApmRegular regular2 = new DictScheduleApmRegular();
                regular2.setApmCode(dto.getApmCode());
                regular2.setRegularId(queueApmArr[0]);
                String[] limit = queueApmArr[1].split("-");
                if (limit.length > 0) {
                    regular2.setMinLimit(Double.parseDouble(limit[0]));
                    if (limit.length > 1) {
                        regular2.setMaxLimit(Double.parseDouble(limit[1]));
                    }
                }
                dictScheduleApmRegularMapper.insert(regular2);
            }
        }
    }

    public DictScheduleApm entity(DictScheduleApmDto dto) {
        DictScheduleApm apm = new DictScheduleApm();
        apm.setApmCode(dto.getApmCode());
        apm.setQueueName(dto.getQueueName());
        apm.setScheduleApm(dto.getScheduleApm());
        apm.setQueueApm(dto.getScheduleApm());
        apm.setScheduleDate(dto.getScheduleDate());
        apm.setWeekDate(dto.getWeekDate());
        apm.setDateStart(dto.getDateStart());
        apm.setDateEnd(dto.getDateEnd());
        apm.setTimeStart(dto.getTimeStart());
        apm.setTimeEnd(dto.getTimeEnd());
        apm.setApmLength(dto.getApmLength());
        apm.setApmFlag(dto.getApmFlag());
        apm.setTimeScheduleLatest(dto.getTimeScheduleLatest());
        apm.setTimeEarliest(dto.getTimeEarliest());
        apm.setTimeSignin(dto.getTimeSignin());
        apm.setDrugTime(dto.getDrugTime());
        apm.setMaxLimit(dto.getMaxLimit());
        apm.setNotice(dto.getNotice());
        apm.setStopFlag(dto.getStopFlag());
        apm.setDaysEarliest(dto.getDaysEarliest());
        apm.setDaysScheduleLatest(dto.getDaysScheduleLatest());
        apm.setTimeScheduleFirst(dto.getTimeScheduleFirst());
        apm.setDaysScheduleFirst(dto.getDaysScheduleFirst());
        apm.setMergeApmCode(dto.getMergeApmCode());
        return apm;
    }

    /**
     * 将通用号源的已预约数量-修改到新增的特殊号源上面
     * @param dto
     * @param isList
     */
    private void saveScheduleApmInfo(DictScheduleApmDto dto, boolean isList) {
        if (isList) {
            UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
            update.eq("APM_CODE", dto.getApmCode());
            updateFormat(update, dto);
            dictScheduleApmMapper.update(entity(dto), update);
        } else {
            boolean isRepeat = isRepeatData(dto);
            if (!isRepeat) {
                dictScheduleApmMapper.insert(entity(dto));
                // 如果是新增号源时段 星期号源或者日期号源，需要将已预约的数据移动到新的特殊号源
                if (!dto.getApmCode().equals(dto.getOldApmCode()) &&
                        (Strings.isNotBlank(dto.getWeekDate()) || Strings.isNotBlank(dto.getScheduleDate()))) {
                    /**
                     * 1. 查询日期已预约的数量
                     * 2. 将日期的已预约数量移动到新的apmcode
                     */
                    // 周特殊号源
                    if (Strings.isNotBlank(dto.getWeekDate()) && StringUtils.isBlank(dto.getScheduleDate())) {
                        /**
                         * 1. 查询到旧时段apm已预约的记录
                         * 2. 找到需要调整的日期
                         */
                        QueryWrapper<ExamScheduleApm> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("APM_CODE", dto.getOldApmCode());
                        queryWrapper.ge("SCHEDULE_DATE", DateUtil.getCurrentDate());
                        List<ExamScheduleApm> examScheduleApms = examScheduleApmMapper.selectList(queryWrapper);
                        // List<String> datas = examScheduleApms.stream().map(x -> x.getScheduleDate()).collect(Collectors.toList());

                        List<ExamScheduleApm> needTransApms = examScheduleApms.stream()
                                .filter(x -> dto.getWeekDate().equals(String.valueOf(DateUtil.getWeekDay(x.getScheduleDate()))))
                                .collect(Collectors.toList());

                        if (CollectionUtils.isNotEmpty(needTransApms)) {
                            List<String> dates = needTransApms.stream().map(x -> x.getScheduleDate()).collect(Collectors.toList());
                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                            updateWrapper.set("APM_CODE", dto.getApmCode());
                            updateWrapper.eq("APM_CODE", dto.getOldApmCode());
                            updateWrapper.in("SCHEDULE_DATE", dates);
                            examScheduleApmMapper.update(null, updateWrapper);
                        }
                    }
                    // 日期特殊号源
                    else if (Strings.isBlank(dto.getWeekDate()) && StringUtils.isNotBlank(dto.getScheduleDate())) {
                        QueryWrapper<ExamScheduleApm> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("APM_CODE", dto.getOldApmCode());
                        queryWrapper.eq("SCHEDULE_DATE", dto.getScheduleDate());
                        ExamScheduleApm examScheduleApm = examScheduleApmMapper.selectOne(queryWrapper);
                        if (Objects.nonNull(examScheduleApm)) {
                            UpdateWrapper<ExamScheduleApm> updateWrapper = new UpdateWrapper<>();
                            updateWrapper.set("APM_CODE", dto.getApmCode());
                            updateWrapper.eq("APM_CODE", dto.getOldApmCode());
                            updateWrapper.eq("SCHEDULE_DATE", dto.getScheduleDate());
                            examScheduleApmMapper.update(null, updateWrapper);
                        }
                    }
                }
            }
        }
    }


    private int updateCommonForStopFlag(Map<String, Object> map, String stopFlag) {
        DictScheduleApm apm = new DictScheduleApm();
        apm.setStopFlag(stopFlag);
        UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
        update.allEq(map);
        update.isNull("WEEK_DATE");
        update.isNull("SCHEDULE_DATE");
        return dictScheduleApmMapper.update(apm, update);
    }

    private int updateDateOrWeekForStopFlag(Map<String, Object> map, String stopFlag) {
        DictScheduleApm apm = new DictScheduleApm();
        apm.setStopFlag(stopFlag);
        String useStatus = "t";
        // 1停用,其他都是启用
        if ("1".equals(stopFlag)) {
            useStatus = "f";
        }
        apm.setUseStatus(useStatus);
        UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
        update.allEq(map);
        return dictScheduleApmMapper.update(apm, update);
    }

    private void getRegularDef(List<DictScheduleApmDto> ampList) {
        if (CollectionUtils.isNotEmpty(ampList)) {
            for (DictScheduleApmDto apm : ampList) {
                boolean isResourceMark = false;
                apm.setResourceMark(COMMON_REGULAR);
                if (StringUtils.isNotBlank(apm.getScheduleDate())) {
                    apm.setResourceMark(DATE_REGULAR);
                    isResourceMark = true;
                }
                if (!isResourceMark && StringUtils.isNotBlank(apm.getWeekDate())) {
                    apm.setResourceMark(WEEK_REGULAR);
                }
                List<DictScheduleApmRegular> apmRegularList = getApmRegular(apm.getApmCode());
                StringBuilder regularName = new StringBuilder();
                StringBuilder regularGroupName = new StringBuilder();
                StringBuilder excludeRegularName = new StringBuilder();
                if (CollectionUtils.isNotEmpty(apmRegularList)) {
                    for (DictScheduleApmRegular apmRegular : apmRegularList) {
                        List<DictScheduleRegularDef> defList = getRegularDefList(apmRegular.getRegularId());
                        if (CollectionUtils.isNotEmpty(defList)) {
                            for (DictScheduleRegularDef dictScheduleRegularDef : defList) {
                                String regularType = dictScheduleRegularDef.getRegularType();
                                if (Regular_Type.equals(regularType)) {
                                    String excludeRegular = dictScheduleRegularDef.getExcludeFlag();
                                    if ("1".equals(excludeRegular)) {
                                        excludeRegularName.append("," + dictScheduleRegularDef.getRegularName());
                                    } else {
                                        regularName.append("," + dictScheduleRegularDef.getRegularName());
                                    }
                                } else {
                                    String maxLimit = (apmRegular.getMaxLimit() == null) ? "" : String.valueOf(apmRegular.getMaxLimit());
                                    regularGroupName.append("," + dictScheduleRegularDef.getRegularName() + "(" + apmRegular.getMinLimit() + "-" + maxLimit + ")");
                                }
                            }
                        }
                    }
                }
                apm.setExcludeRegularName(StringUtils.isNotBlank(excludeRegularName.toString()) ? excludeRegularName.substring(1) : "");
                apm.setRegularName(StringUtils.isNotBlank(regularName.toString()) ? regularName.substring(1) : "");
                apm.setRegularGroupName(StringUtils.isNotBlank(regularGroupName.toString()) ? regularGroupName.substring(1) : "");
            }
        }
    }

    private String getScheduleApmCode(DictScheduleApm apm, String resourceMark) {
        QueryWrapper<DictScheduleApm> query = new QueryWrapper<>();
        query.select("APM_CODE");
        query.eq("QUEUE_NAME", apm.getQueueName());
        query.eq("SCHEDULE_APM", apm.getScheduleApm());
        query.eq("DATE_START", apm.getDateStart());
        query.eq("DATE_END", apm.getDateEnd());
        if (DATE_REGULAR.equals(resourceMark)) {
            query.eq("SCHEDULE_DATE", apm.getScheduleDate());
        } else if (WEEK_REGULAR.equals(resourceMark)) {
            query.eq("WEEK_DATE", apm.getWeekDate());
        }
        List<DictScheduleApm> apmList = dictScheduleApmMapper.selectList(query);
        String apmCode = "";
        if (apmList != null && apmList.size() > 0) {
            apmCode = apmList.get(0).getApmCode();
        }
        return apmCode;
    }

    private List<DictScheduleApmRegular> getApmRegular(String apmCode) {
        QueryWrapper<DictScheduleApmRegular> regular = new QueryWrapper<>();
        regular.select("REGULAR_ID", "MIN_LIMIT", "MAX_LIMIT");
        regular.eq("APM_CODE", apmCode);
        return dictScheduleApmRegularMapper.selectList(regular);
    }

    private List<DictScheduleRegularDef> getRegularDefList(String regularId) {
        QueryWrapper<DictScheduleRegularDef> def = new QueryWrapper<>();
        def.select(new String[]{"REGULAR_NAME", "REGULAR_TYPE", "EXCLUDE_FLAG"});
        def.eq("REGULAR_ID", regularId);
        def.in("REGULAR_TYPE", 0, 3);
        return dictScheduleRegularDefMapper.selectList(def);
    }

    @Override
    public List<DictScheduleApmRegularDto> getRegularDefInfo(DictScheduleApmRegularDto dto) {
        return dictScheduleApmRegularMapper.getRegularDefInfo(dto);
    }

    private boolean belongCalendar(String nowTime, String beginTime, String endTime) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar date = Calendar.getInstance();
        date.setTime(df.parse(nowTime));
        Calendar begin = Calendar.getInstance();
        begin.setTime(df.parse(beginTime));
        Calendar end = Calendar.getInstance();
        end.setTime(df.parse(endTime));
        return (date.after(begin) && date.before(end)) || (nowTime.compareTo(beginTime) == 0 || nowTime.compareTo(endTime) == 0);
    }

    /**
     * 开始日期是否大于结束日期
     *
     * @param dateStart
     * @param dateEnd
     * @return
     * @throws ParseException
     */
    private boolean isNewYear(String dateStart, String dateEnd) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("MM-dd");
        Date dt1 = df.parse(dateStart);
        Date dt2 = df.parse(dateEnd);
        return dt1.after(dt2);
    }

    private boolean isCycle(String calendarDate, String start, String end) {
        try {
            String dateStart = start;
            String dateEnd = end;
            boolean rangeType = start.length() > 5;
            if (!rangeType) {
                boolean isPass = isNewYear(start, end);
                Calendar cale = Calendar.getInstance();
                String currentYear = String.valueOf(cale.get(1));
                String year = calendarDate.split("-")[0];
                int y = Integer.parseInt(year) - Integer.parseInt(currentYear);
                dateStart = year + "-" + start;
                dateEnd = year + "-" + end;
                if (isPass) {
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
                    Date dt3 = df1.parse(calendarDate);
                    Date dt4 = df1.parse(year + "-" + end);
                    boolean isPassy = dt3.after(dt4);
                    if (calendarDate.equals(year + "-" + end)) {
                        isPassy = true;
                    }
                    if (y >= 0) {
                        if (isPassy) {
                            dateEnd = String.valueOf(Integer.parseInt(year) + 1) + "-" + end;
                        } else {
                            dateStart = String.valueOf(Integer.parseInt(year) - 1) + "-" + start;
                        }
                    } else if (y < 0) {
                        dateEnd = String.valueOf(Integer.parseInt(year) + 1) + "-" + end;
                    }
                }
            }
            boolean isCycle = belongCalendar(calendarDate, dateStart, dateEnd);
            return isCycle;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public Map<String, Object> getCalendarColor(DictScheduleApmDto apm) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
        String calendarDate = apm.getCalendarDate();
        int dayLen = 0;
        try {
            dayLen = DateUtil.getMonthDay(df.parse(calendarDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String dateStart = apm.getDateStart();
        String dateEnd = apm.getDateEnd();
        Map<String, Object> map = new HashMap<String, Object>();
        List<String> resourceMark = new ArrayList<String>();
        for (int i = 1; i <= dayLen; ++i) {
            String day = String.valueOf(i);
            if (i < 10) {
                day = Regular_Type + i;
            }
            String date = calendarDate + "-" + day;
            boolean isScheduleDate = false;
            boolean isCycle = isCycle(date, dateStart, dateEnd);
            if (!isCycle) {
                resourceMark.add(NOT_REGULAR);
            } else {
                QueryWrapper<DictScheduleApm> dateQuery = new QueryWrapper<>();
                dateQuery.eq("QUEUE_NAME", apm.getQueueName());
                dateQuery.eq("SCHEDULE_DATE", date);
                dateQuery.eq("DATE_START", dateStart);
                dateQuery.eq("DATE_END", dateEnd);
                dateQuery.ne("STOP_FLAG", "2");
                isScheduleDate = (dictScheduleApmMapper.selectCount(dateQuery) > 0);
                if (isScheduleDate) {
                    resourceMark.add(DATE_REGULAR);
                } else {
                    QueryWrapper<DictScheduleApm> weekQuery = new QueryWrapper<>();
                    weekQuery.eq("QUEUE_NAME", apm.getQueueName());
                    weekQuery.eq("DATE_START", dateStart);
                    weekQuery.eq("DATE_END", dateEnd);
                    weekQuery.ne("STOP_FLAG", "2");
                    df = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        weekQuery.eq("WEEK_DATE", DateUtil.getNumberWeek(df.parse(date)));
                    } catch (ParseException e2) {
                        e2.printStackTrace();
                    }
                    isScheduleDate = (dictScheduleApmMapper.selectCount(weekQuery) > 0);
                    if (isScheduleDate) {
                        resourceMark.add(WEEK_REGULAR);
                    } else {
                        resourceMark.add(COMMON_REGULAR);
                    }
                }
            }
        }
        map.put("resourceMark", resourceMark);
        QueryWrapper<DictExamQueue> query = new QueryWrapper<>();
        query.select("EXAM_CLASS");
        query.eq("QUEUE_TYPE", Regular_Type);
        query.eq("QUEUE_NAME", apm.getQueueName());
        List<DictExamQueue> list = dictExamQueueMapper.selectList(query);
        String examClass = list.get(0).getExamClass();
        map.put("examClass", examClass);
        return map;
    }

    /***
     * 获取号源周期列表
     * @param apm
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult getCycleList(DictScheduleApmDto apm) {
        DictCommonUseDto dcu = new DictCommonUseDto();
        dcu.setName(SCHEDULE_APM);
        dcu.setReserve1(apm.getQueueName());
        dcu.setExamClass(apm.getExamClass());
        List<DictCommonUse> dcuList = dictCommonUseService.getList(dcu);
        // 每个队列的号源周期只能有一个
        if (dcuList.size() > 1) {
            return JsonResultUtil.failure("时段周期字典数据错误");
        }

        List<String> dates = new ArrayList<String>();
        if (dcuList != null && dcuList.size() > 0) {
            // 日期列表
            String reserve4 = dcuList.get(0).getReserve4();
            if (StringUtils.isNoneEmpty(reserve4)) {
                String[] split = reserve4.split(",");
                for (String date : split) {
                    dates.add(date);
                }
            }
        } else {
            QueryWrapper<DictScheduleApm> queryWrapper = new QueryWrapper();
            queryWrapper.select("DATE_START", "DATE_END");
            queryWrapper.eq("QUEUE_NAME", apm.getQueueName());
            queryWrapper.isNotNull("DATE_START");
            queryWrapper.groupBy("DATE_START", "DATE_END");
            queryWrapper.orderByAsc("DATE_START");
            List<DictScheduleApm> apmList = dictScheduleApmMapper.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(apmList)) {
                return JsonResultUtil.success("未设置号源周期");
            }
            // 开始日期内容长度-判断是不是有年
            int length = apmList.get(0).getDateStart().length();
            StringBuffer dateSubStr = new StringBuffer();
            for (DictScheduleApm apmItem : apmList) {
                // 开始和结束日期
                String date2 = apmItem.getDateStart() + "~" + apmItem.getDateEnd();
                dateSubStr.append("," + date2);
                dates.add(date2);

                if (length != apmItem.getDateStart().length()) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return JsonResultUtil.failure("不允许存在多种不同类型的周期");
                }

            }
            DictCommonUseDto dc = new DictCommonUseDto();
            dc.setName(SCHEDULE_APM);
            dc.setValue("号源周期");
            dc.setExamClass(apm.getExamClass());
            dc.setReserve1(apm.getQueueName());
            // 去掉最开始的逗号
            dc.setReserve4(dateSubStr.substring(1));

            boolean saveResult = dictCommonUseService.save(dc);
            if (!saveResult) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return JsonResultUtil.failure("初始化数据错误");
            }
        }

        if (CollectionUtils.isNotEmpty(dates)) {
            List<DictScheduleApm> scheduleApms = new ArrayList<>();
            int dateLength = dates.get(0).split("~")[0].length();
            for (String dateItem : dates) {
                String[] dateArr = dateItem.split("~");
                DictScheduleApm dsa = new DictScheduleApm();
                dsa.setApmType(Regular_Type);
                dsa.setDateStart(dateArr[0]);
                dsa.setDateEnd(dateArr[1]);
                if (dateLength != dateArr[0].length()) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return JsonResultUtil.failure("不允许存在多种不同类型的周期");
                }
                try {
                    String dateStart = dateArr[0];
                    String dateEnd = dateArr[1];
                    //String formatter = "yyyy-MM-dd";
                    if (dateStart.length() < 6) {
                        // 没有年份
                        // 是否跨年
                        boolean isPass = isNewYear(dateArr[0], dateArr[1]);
                        Calendar cale = Calendar.getInstance();
                        String currentYear = String.valueOf(cale.get(1));

                        dateStart = currentYear + "-" + dateArr[0];
                        dateEnd = currentYear + "-" + dateArr[1];
                        if (isPass) {
                            dateEnd = Integer.parseInt(currentYear) + 1 + "-" + dateArr[1];
                        }
                    }
                    Date startDate = DateUtil.parse(dateStart, DateUtil.FORMAT_DATE);
                    Date endDate = DateUtil.parse(dateEnd, DateUtil.FORMAT_DATE);
                    Date currentDate = new Date();

                    if (startDate.getTime() <= currentDate.getTime()
                            && endDate.getTime() >= currentDate.getTime()) {
                        dsa.setApmType("1");
                    }
                } catch (Exception e) {
                    logger.error("getCycleList:" + e.getMessage(), e);
                    e.printStackTrace();
                }
                scheduleApms.add(dsa);
            }
            return JsonResultUtil.success("成功", scheduleApms);
        }
        return JsonResultUtil.success("未设置号源周期");
    }

    /**
     * 获取检查队列，保存时段
     *
     * @param dto
     */
    @Override
    public void getDictExamQueueSaveApm(DictExamQueueDto dto) {
        QueryWrapper<DictExamQueue> query = new QueryWrapper();
        query.select("QUEUE_NAME");
        query.eq("EXAM_CLASS", dto.getExamClass());
        query.ne("QUEUE_NAME", dto.getQueueName());

        // 查询队列名称列表
        List<DictExamQueue> list = dictExamQueueMapper.selectList(query);
        String queueName = dto.getQueueName();
        if (list != null && list.size() > 0) {
            queueName = list.get(0).getQueueName();
        }

        QueryWrapper<DictScheduleApm> dsa = new QueryWrapper();
        dsa.eq("QUEUE_NAME", queueName);
        dsa.isNull("SCHEDULE_DATE")
                .isNull("WEEK_DATE");

        List<DictScheduleApm> dsaList = dictScheduleApmMapper.selectList(dsa);
        for (DictScheduleApm apmDto : dsaList) {
            DictScheduleApmDto apm = new DictScheduleApmDto();
            String apmCode = dictSerialService.getSerialId("APM_CODE");
            apm.setApmCode(apmCode);
            apm.setQueueName(dto.getQueueName());
            apm.setScheduleApm(apmDto.getScheduleApm());
            apm.setDateStart(apmDto.getDateStart());
            apm.setDateEnd(apmDto.getDateEnd());
            apm.setTimeStart(apmDto.getTimeStart());
            apm.setTimeEnd(apmDto.getTimeEnd());
            apm.setApmLength(apmDto.getApmLength());
            apm.setApmFlag(apmDto.getApmFlag());
            apm.setExamClass(dto.getExamClass());
            apm.setTimeSignin(apmDto.getTimeSignin());
            apm.setStopFlag("1");
            apm.setResourceMark(COMMON_REGULAR);
            boolean isRepeat = isRepeatData(apm);
            if (!isRepeat) {
                dictScheduleApmMapper.insert(apm);
            }
            examSyslogService.saveExamSyslogForDesc(ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_COMMON.name(), ConstantsUtil.OperateName.INSERT.getDesc(), apm);
        }
    }

    /**
     * 记录删除日志包括下面的预约时段
     *
     * @param dto
     */
    @Override
    public void examSyslog4DeleteQueue(DictExamQueue dto) {
        if (StringUtils.isNotBlank(dto.getQueueName())) {
            QueryWrapper<DictScheduleApm> dsa = new QueryWrapper<>();
            dsa.eq("QUEUE_NAME", dto.getQueueName());
            List<DictScheduleApm> dsaList = dictScheduleApmMapper.selectList(dsa);
            for (DictScheduleApm apmDto : dsaList) {
                DictScheduleApmDto apm = new DictScheduleApmDto();
                BeanUtils.copyProperties(apmDto, apm);
                apm.setExamClass(dto.getExamClass());
                // 保存日志
                updateExamSyslog(apm, ConstantsUtil.OperateName.DELETE.getDesc());
            }
        }
    }

    private boolean isCycleRange(DictScheduleApmDto dto) {
        int dayLen = 0;
        String calendarDate = dto.getCalendarDate();
        String scheduleDate = dto.getScheduleDate();
        String weekDate = dto.getWeekDate();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
        try {
            dayLen = DateUtil.getMonthDay(df.parse(calendarDate));
        } catch (ParseException e) {
            logger.error("日期格式化错误", e);
        }
        String dateStart = dto.getDateStart();
        String dateEnd = dto.getDateEnd();
        for (int i = 1; i <= dayLen; ++i) {
            String days = String.valueOf(i);
            if (i < 10) {
                days = Regular_Type + i;
            }
            String date = calendarDate + "-" + days;
            if (StringUtils.isNotBlank(scheduleDate)) {
                String day = scheduleDate.split("-")[2];
                if (i != Integer.parseInt(day)) {
                    continue;
                }
            } else if (StringUtils.isNotBlank(weekDate)) {
                SimpleDateFormat dfWeek = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    String week = DateUtil.getNumberWeek(dfWeek.parse(date));
                    if (!weekDate.equals(week)) {
                        continue;
                    }
                } catch (ParseException e2) {
                    logger.error("日期格式化错误", e2);
                }
            }
            boolean isCycle = isCycle(date, dateStart, dateEnd);
            if (isCycle) {
                return isCycle;
            }
        }
        return false;
    }

    public void removeSourceCache() {
        EhCacheUtil.removeForCacheName(ConstantsUtil.EhCacheName.regularCache.name());
        EhCacheUtil.removeForCacheName(ConstantsUtil.EhCacheName.ruleResultCache.name());
    }

    @Override
    public List<DictScheduleRegularDef> getRegularDefList(DictScheduleRegularDefDto dto) {
        QueryWrapper<DictScheduleRegularDef> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("REGULAR_ID", "REGULAR_NAME", "REGULAR_MEMO", "nvl(EXCLUDE_FLAG,0) excludeFlag");
        queryWrapper.eq("EXAM_CLASS", dto.getExamClass());
        queryWrapper.eq("REGULAR_TYPE", dto.getRegularType());
        queryWrapper.orderByAsc("SORT_NO", "REGULAR_NAME");
        return dictScheduleRegularDefService.list(queryWrapper);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult manyCancelModify(DictScheduleApmDto dto) {
        List<String> timeStartList = CommonUtil.split2List(dto.getTimeStart());
        DictScheduleApmDto apm = new DictScheduleApmDto();
        apm.setQueueName(dto.getQueueName());
        apm.setTimeStarts((List) timeStartList);
        apm.setDateStart(dto.getDateStart());
        apm.setDateEnd(dto.getDateEnd());
        String[] dateArr = dto.getScheduleDate().split(",");
        if (dto.getResourceMark().equals(WEEK_REGULAR)) {
            dateArr = dto.getWeekDate().split(",");
        }
        if (dateArr.length == 0) {
            return JsonResultUtil.failure("无可取消号源");
        }
        for (String date : dateArr) {
            List<DictScheduleApmDto> dateList = new ArrayList<DictScheduleApmDto>();
            if (dto.getResourceMark().equals(DATE_REGULAR)) {
                apm.setScheduleDate(date);
                dateList = dictScheduleApmMapper.getDateScheduleApm(apm);
            } else if (dto.getResourceMark().equals(WEEK_REGULAR)) {
                apm.setWeekDate(date);
                dateList = dictScheduleApmMapper.getWeekScheduleApm(apm);
            }
            if (dateList != null) {
                if (dateList.size() != 0) {
                    DictScheduleApmDto dsa = new DictScheduleApmDto();
                    dsa.setResourceMark(dto.getResourceMark());
                    dsa.setExamClass(dto.getExamClass());
                    StringBuffer sb = new StringBuffer();
                    for (DictScheduleApmDto list : dateList) {
                        sb.append("," + dto.getResourceMark() + "=" + list.getApmCode() + "=" + date);
                    }
                    dsa.setQueueScheduleApm(sb.substring(1));
                    cancelModify(dsa);
                }
            }
        }
        return JsonResultUtil.success("成功");
    }

    /**
     * 批量修改号源周期
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult manyBatchModifySchedule(DictScheduleApmDto dto) {
        if (StringUtils.isBlank(dto.getScheduleDate()) && !DATE_REGULAR.equals(dto.getResourceMark())) {
            return JsonResultUtil.failure("号源类型入参有误");
        }
        String[] dateArr = dto.getScheduleDate().split(",");
        if (dto.getResourceMark().equals(WEEK_REGULAR)) {
            dateArr = dto.getWeekDate().split(",");
        }
        List<String> timeStartList = CommonUtil.split2List(dto.getTimeStart());
        dto.setTimeStart(null);
        DictScheduleApmDto apmCommon = new DictScheduleApmDto();
        apmCommon.setQueueName(dto.getQueueName());
        apmCommon.setTimeStarts(timeStartList);
        apmCommon.setDateStart(dto.getDateStart());
        apmCommon.setDateEnd(dto.getDateEnd());
        List<DictScheduleApmDto> commonList = dictScheduleApmMapper.getCommonScheduleApm(apmCommon);
        if (commonList == null || commonList.size() == 0) {
            return JsonResultUtil.failure("未查询到可修改号源");
        }
        Map<String, String> map = new HashMap<>();
        for (DictScheduleApm dsa : commonList) {
            map.put(dsa.getTimeStart(), dsa.getApmCode());
        }
        for (String date : dateArr) {
            DictScheduleApmDto apm = new DictScheduleApmDto();
            apm.setQueueName(dto.getQueueName());
            apm.setTimeStarts(timeStartList);
            List<String> apmCodes = new ArrayList<>();
            Map<String, String> mapDate = new HashMap<>();
            mapDate.putAll(map);
            if (dto.getResourceMark().equals(DATE_REGULAR)) {
                dto.setScheduleDate(date);
                apm.setScheduleDate(date);
                List<DictScheduleApmDto> dateList = dictScheduleApmMapper.getDateScheduleApm(apm);
                if (dateList != null && dateList.size() > 0) {
                    for (DictScheduleApm dsa2 : dateList) {
                        if ("2".equals(dsa2.getStopFlag())) {
                            continue;
                        }
                        mapDate.put(dsa2.getTimeStart(), dsa2.getApmCode());
                    }
                }
            }
            if (dto.getResourceMark().equals(WEEK_REGULAR)) {
                dto.setWeekDate(date);
                apm.setWeekDate(date);
                apm.setDateStart(dto.getDateStart());
                apm.setDateEnd(dto.getDateEnd());
                List<DictScheduleApmDto> dateList = dictScheduleApmMapper.getWeekScheduleApm(apm);
                if (dateList != null && dateList.size() > 0) {
                    for (DictScheduleApm dsa2 : dateList) {
                        if ("2".equals(dsa2.getStopFlag())) {
                            continue;
                        }
                        mapDate.put(dsa2.getTimeStart(), dsa2.getApmCode());
                    }
                }
            }
            mapDate.forEach((k, v) -> apmCodes.add(v));
            dto.setApmCode(StringUtils.join(apmCodes, ","));
            batchModifySchedule(dto);
        }
        return JsonResultUtil.success("成功");
    }

    @Override
    public JsonResult batchModifySchedule(DictScheduleApmDto dto) {
        removeSourceCache();
        List<String> apmCodes = (List<String>) CommonUtil.split2List(dto.getApmCode());
        for (String apmCode : apmCodes) {
            DictScheduleApm apm = dictScheduleApmService.selectOneByApmCode(apmCode);
            if (!apm.getQueueName().equals(dto.getQueueName())) {
                continue;
            }
            String week = "";
            String apmResourceMark = COMMON_REGULAR;
            if (StringUtils.isNotBlank(apm.getScheduleDate())) {
                apmResourceMark = DATE_REGULAR;
            } else if (StringUtils.isNotBlank(apm.getWeekDate())) {
                week = apm.getWeekDate() + "=";
                apmResourceMark = WEEK_REGULAR;
            }
            String resourceMark = dto.getResourceMark();
            if (StringUtils.isBlank(resourceMark)) {
                if (StringUtils.isNotBlank(dto.getScheduleDate())) {
                    resourceMark = DATE_REGULAR;
                } else if (StringUtils.isNotBlank(dto.getWeekDate())) {
                    resourceMark = WEEK_REGULAR;
                }
            }
            if (!apmResourceMark.equals(resourceMark)) {
                DictScheduleApmDto dsa = new DictScheduleApmDto();
                dsa.setExamClass(dto.getExamClass());
                dsa.setQueueName(dto.getQueueName());
                dsa.setScheduleDate(dto.getScheduleDate());
                dsa.setWeekDate(dto.getWeekDate());
                dsa.setStopFlag(StringUtils.isBlank(dto.getStopFlag()) ? Regular_Type : dto.getStopFlag());
                String queueScheduleApm = apmResourceMark + "=" + apm.getScheduleApm() + "=" + week + apm.getDateStart() + "=" + apm.getDateEnd();
                dsa.setQueueScheduleApm(queueScheduleApm);
                startOrStopForSource(dsa);
                dsa.setScheduleApm(apm.getTimeStart() + "~" + apm.getTimeEnd());
                dsa.setDateStart(apm.getDateStart());
                dsa.setDateEnd(apm.getDateEnd());
                apmCode = dsa.getApmCode();
            }
            dto.setApmCode(apmCode);
            UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
            update.eq("APM_CODE", apmCode);
            dictScheduleApmMapper.update(entity(dto), update);
            String regularDefSchedule = dto.getRegularDefSchedule();
            if (StringUtils.isNotBlank(regularDefSchedule)) {
                QueryWrapper<DictScheduleApmRegular> query = new QueryWrapper<>();
                query.eq("APM_CODE", dto.getApmCode());
                query.isNull("MIN_LIMIT");
                dictScheduleApmRegularMapper.delete(query);
                String[] split;
                String[] defArr = split = regularDefSchedule.split(",");
                for (String regularId : split) {
                    DictScheduleApmRegular regular = new DictScheduleApmRegular();
                    regular.setApmCode(dto.getApmCode());
                    regular.setRegularId(regularId);
                    dictScheduleApmRegularMapper.insert(regular);
                }
            }
            String regularSchedule = dto.getRegularSchedule();
            if (StringUtils.isNotBlank(regularSchedule)) {
                QueryWrapper<DictScheduleApmRegular> query2 = new QueryWrapper<>();
                query2.eq("APM_CODE", dto.getApmCode());
                query2.isNotNull("MIN_LIMIT");
                dictScheduleApmRegularMapper.delete(query2);
                String[] split2;
                String[] regularArr = split2 = regularSchedule.split(",");
                for (String regulars : split2) {
                    String[] queueApmArr = regulars.split("=");
                    DictScheduleApmRegular regular2 = new DictScheduleApmRegular();
                    regular2.setApmCode(dto.getApmCode());
                    regular2.setRegularId(queueApmArr[0]);
                    String[] limit = queueApmArr[1].split("-");
                    if (limit.length > 0) {
                        regular2.setMinLimit(Double.parseDouble(limit[0]));
                        if (limit.length > 1) {
                            regular2.setMaxLimit(Double.parseDouble(limit[1]));
                        }
                    }
                    dictScheduleApmRegularMapper.insert(regular2);
                }
            }
            updateExamSyslog(dto, ConstantsUtil.OperateName.UPDATE.getDesc());
        }
        return JsonResultUtil.success("成功");
    }

    @Override
    public JsonResult getManySourceList(DictScheduleApmDto dto) {
        DictScheduleApmDto dsa = new DictScheduleApmDto();
        dsa.setCalendarDate(dto.getCalendarDate());
        dsa.setExamClass(dto.getExamClass());
        dsa.setDateEnd(dto.getDateEnd());
        dsa.setDateStart(dto.getDateStart());
        dsa.setQueueName(dto.getQueueName());
        if (StringUtils.isNotBlank(dto.getScheduleDate())) {
            dsa.setScheduleDate(dto.getScheduleDate().split(",")[0]);
        }
        if (StringUtils.isNotBlank(dto.getWeekDate())) {
            dsa.setWeekDate(dto.getWeekDate().split(",")[0]);
        }
        List<DictScheduleApmDto> list = getSourceList(dsa);
        List<String> timeStart = CommonUtil.split2List(dto.getTimeStart());
        if (list != null && list.size() > 0) {
            for (DictScheduleApmDto apm : list) {
                if (timeStart.contains(apm.getTimeStart())) {
                    if (StringUtils.isBlank(dto.getResourceMark())) {
                        apm.setResourceMark(null);
                    }
                    if (StringUtils.isBlank(dto.getApmFlag())) {
                        apm.setApmFlag(dto.getApmFlag());
                    }
                    if (dto.getMaxLimit() == null) {
                        apm.setMaxLimit(dto.getMaxLimit());
                    }
                    if (StringUtils.isBlank(dto.getStopFlag())) {
                        apm.setStopFlag(null);
                    }
                    if (StringUtils.isBlank(dto.getRegularDefScheduleName())) {
                        apm.setRegularName(null);
                        apm.setExcludeRegularName(null);
                    }
                    if (StringUtils.isBlank(dto.getRegularScheduleName())) {
                        apm.setRegularGroupName(null);
                    }
                    if (StringUtils.isBlank(dto.getTimeEarliest())) {
                        apm.setTimeEarliest(null);
                    }
                    if (StringUtils.isBlank(dto.getTimeScheduleFirst())) {
                        apm.setTimeScheduleFirst(null);
                    }
                    if (StringUtils.isBlank(dto.getTimeScheduleLatest())) {
                        apm.setTimeScheduleLatest(null);
                    }
                    if (StringUtils.isBlank(dto.getTimeSignin())) {
                        apm.setTimeSignin(null);
                    }
                    if (Objects.isNull(dto.getDaysEarliest())) {
                        apm.setDaysEarliest(null);
                    }
                    if (Objects.isNull(dto.getDaysScheduleFirst())) {
                        apm.setDaysScheduleFirst(null);
                    }
                    if (Objects.isNull(dto.getDaysScheduleLatest())) {
                        apm.setDaysScheduleLatest(null);
                    }
                    if (StringUtils.isBlank(dto.getDrugTime())) {
                        apm.setDrugTime(null);
                    }
                } else {
                    apm.setResourceMark(null);
                    apm.setApmFlag(null);
                    apm.setMaxLimit(null);
                    apm.setStopFlag(null);
                    apm.setRegularName(null);
                    apm.setRegularGroupName(null);
                    apm.setExcludeRegularName(null);
                    apm.setTimeEarliest(null);
                    apm.setTimeScheduleFirst(null);
                    apm.setTimeScheduleLatest(null);
                    apm.setTimeSignin(null);
                    apm.setDaysEarliest(null);
                    apm.setDaysScheduleFirst(null);
                    apm.setDaysScheduleLatest(null);
                    apm.setDrugTime(null);
                }
                apm.setNotice(null);
            }
        }
        return JsonResultUtil.success("成功", list);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public JsonResult copyDictScheduleApm(DictScheduleApmDto dto) {
        List<String> apmCodes = CommonUtil.split2List(dto.getApmCode());
        for (String str : apmCodes) {
            String[] arr = str.split("=");
            if (arr.length < 2) {
                continue;
            }
            String oldApmCode = arr[1];
            DictScheduleApm dsa = dictScheduleApmService.selectOneByApmCode(oldApmCode);
            DictScheduleApmDto apmDto = new DictScheduleApmDto();
            BeanUtils.copyProperties(dsa, apmDto);
            apmDto.setWeekDate(null);
            List<String> copyScheduleDateList = (List<String>) CommonUtil.split2List(dto.getScheduleDate());
            DictScheduleApmDto apm = new DictScheduleApmDto();
            apm.setDateStart(dsa.getDateStart());
            apm.setDateEnd(dsa.getDateEnd());
            apm.setQueueName(dto.getQueueName());
            apm.setTimeStart(dsa.getTimeStart());
            apm.setTimeEnd(dsa.getTimeEnd());
            for (String copyScheduleDate : copyScheduleDateList) {
                apm.setScheduleDate(copyScheduleDate);
                DictScheduleApm dictScheduleApm = dictScheduleApmService.getInfo(apm);
                apmDto.setScheduleDate(copyScheduleDate);
                if (Regular_Type.equals(arr[0]) || "1".equals(arr[0])) {
                    String apmCode = "";
                    if (dictScheduleApm != null) {
                        apmCode = dictScheduleApm.getApmCode();
                        apmDto.setApmCode(apmCode);
                        UpdateWrapper<DictScheduleApm> update = new UpdateWrapper<>();
                        update.eq("APM_CODE", dictScheduleApm.getApmCode());
                        updateFormat(update, apmDto);
                        dictScheduleApmMapper.update(entity(apmDto), update);
                    } else {
                        apmCode = dictSerialService.getSerialId("APM_CODE");
                        apmDto.setApmCode(apmCode);
                        dictScheduleApmMapper.insert(entity(apmDto));
                    }
                    if (Regular_Type.equals(arr[0])) {
                        copyDictScheduleApmRegular(oldApmCode, apmCode, apmDto);
                    }
                }
                if ("2".equals(arr[0])) {
                    String apmCode = "";
                    if (dictScheduleApm != null) {
                        apmCode = dictScheduleApm.getApmCode();
                    }
                    if (StringUtils.isBlank(apmCode)) {
                        apm.setScheduleDate(null);
                        apm.setWeekDate(DateUtil.getWeek(copyScheduleDate));
                        DictScheduleApm dsapm = dictScheduleApmService.getInfo(apm);
                        if (dsapm == null || "2".equals(dsapm.getStopFlag())) {
                            apm.setScheduleDate(null);
                            apm.setWeekDate(null);
                            dsapm = dictScheduleApmService.getInfo(apm);
                        }
                        apmCode = dictSerialService.getSerialId("APM_CODE");
                        DictScheduleApmDto dictScheduleApmDto = new DictScheduleApmDto();
                        BeanUtils.copyProperties(dsapm, dictScheduleApmDto);
                        dictScheduleApmDto.setApmCode(apmCode);
                        dictScheduleApmDto.setWeekDate(null);
                        dictScheduleApmDto.setScheduleDate(copyScheduleDate);
                        dictScheduleApmMapper.insert(entity(dictScheduleApmDto));
                    }
                    copyDictScheduleApmRegular(oldApmCode, apmCode, new DictScheduleApmDto());
                }
            }
        }
        return JsonResultUtil.success("复制成功");
    }

    @Override
    public JsonResult sourceTotalEdit(DictScheduleApmDto dto) {
        if (StringUtils.isNotBlank(dto.getScheduleDate()) && StringUtils.isNotBlank(dto.getWeekDate())) {
            return JsonResultUtil.failure("日期和星期不能同时入参");
        }
        List<DictScheduleApmDto> commRList = dictScheduleApmMapper.getExamQueueApm(dto);
        double limit = BigDecimalUtil.divide(dto.getMaxLimit(), commRList.size(), 0, 1);
        double remainder = BigDecimalUtil.remainder(dto.getMaxLimit(), commRList.size(), 0);
        if (limit == 0.0 && remainder == 0.0) {
            return JsonResultUtil.failure("无可分配的号源数");
        }
        double tatal = 0.0;
        DictScheduleApmDto dsaDto = new DictScheduleApmDto();
        dsaDto.setWeekDate(dto.getWeekDate());
        dsaDto.setScheduleDate(dto.getScheduleDate());
        dsaDto.setDateStart(dto.getDateStart());
        dsaDto.setDateEnd(dto.getDateEnd());
        for (DictScheduleApmDto dsa : commRList) {
            double maxLimit = limit;
            if (remainder > 0.0) {
                ++maxLimit;
                --remainder;
            }
            tatal += maxLimit;
            if (tatal > dto.getMaxLimit()) {
                maxLimit = 0.0;
            }
            dsaDto.setTimeStart(dsa.getTimeStart());
            dsaDto.setTimeEnd(dsa.getTimeEnd());
            String resourceMark = DATE_REGULAR;
            List<DictScheduleApmDto> list = new ArrayList<>();
            if (StringUtils.isNotBlank(dto.getScheduleDate())) {
                list = dictScheduleApmMapper.getOneDateExamQueueApm(dsaDto);
                if (CollectionUtils.isNotEmpty(list)) {
                    resourceMark = WEEK_REGULAR;
                    dsaDto.setWeekDate(DateUtil.getWeek(dto.getScheduleDate()));
                    list = dictScheduleApmMapper.getOneWeekExamQueueApm(dsaDto);
                }
            }
            if (StringUtils.isNotBlank(dto.getWeekDate())) {
                resourceMark = WEEK_REGULAR;
                list = dictScheduleApmMapper.getOneWeekExamQueueApm(dsaDto);
            }
            String apmCode = dsa.getApmCode();
            if (CollectionUtils.isNotEmpty(list)) {
                apmCode = list.get(0).getApmCode();
            } else {
                resourceMark = COMMON_REGULAR;
            }
            DictScheduleApmDto dictScheduleApm = new DictScheduleApmDto();
            dictScheduleApm.setApmCode(apmCode);
            dictScheduleApm.setExamClass(dto.getExamClass());
            dictScheduleApm.setQueueName(dto.getQueueName());
            dictScheduleApm.setResourceMark(resourceMark);
            dictScheduleApm.setWeekDate(dto.getWeekDate());
            dictScheduleApm.setScheduleDate(dto.getScheduleDate());
            dictScheduleApm.setMaxLimit(maxLimit);
            dictScheduleApm.setStopFlag(Regular_Type);
            updateScheduleApmMaxLimit(dictScheduleApm);
        }
        return JsonResultUtil.success("成功");
    }

    @Override
    public Map<String, Object> getWholeCalendarColor(DictScheduleApmDto apm) {
        Map<String, Object> map = new HashMap<String, Object>();
        DictExamQueueDto deq = new DictExamQueueDto();
        deq.setExamClassList(CommonUtil.split2List(apm.getExamClass()));
        List<DictExamQueue> list = dictExamQueueServiceImpl.selectList(deq);
        if (CollectionUtils.isNotEmpty(list)) {
            return map;
        }
        List<String> queueNameList = new ArrayList<String>();
        for (DictExamQueue d : list) {
            queueNameList.add(d.getQueueName());
        }
        int dayLen = 0;
        dayLen = DateUtil.getMonthDay(DateUtil.parse(apm.getCalendarDate(), "yyyy-MM"));
        String dateStart = apm.getDateStart();
        String dateEnd = apm.getDateEnd();
        String timeStart = apm.getTimeStart();
        String timeEnd = apm.getTimeEnd();
        String apmType = apm.getApmType();
        String queueName = apm.getQueueName();
        List<String> queueNames = CommonUtil.split2List(queueName);
        queueNameList.removeAll(queueNames);
        queueNameList.addAll(queueNames);
        List<String> resourceMark = new ArrayList<>();
        for (int i = 1; i <= dayLen; ++i) {
            String day = String.valueOf(i);
            if (i < 10) {
                day = Regular_Type + i;
            }
            String date = apm.getCalendarDate() + "-" + day;
            boolean isScheduleDate = false;
            boolean isCycle = isCycle(date, dateStart, dateEnd);
            if (!isCycle) {
                resourceMark.add(NOT_REGULAR);
            } else {
                QueryWrapper<DictScheduleApm> dateQuery = new QueryWrapper<>();
                dateQuery.in("QUEUE_NAME", queueNameList);
                dateQuery.eq("SCHEDULE_DATE", date);
                dateQuery.eq("DATE_START", dateStart);
                dateQuery.eq("DATE_END", dateEnd);
                dateQuery.eq("TIME_START", timeStart);
                dateQuery.eq("TIME_END", timeEnd);
                dateQuery.ne("STOP_FLAG", "2");
                if (StringUtils.isBlank(apmType)) {
                    dateQuery.isNull("APM_TYPE");
                } else {
                    dateQuery.eq("APM_TYPE", apmType);
                }
                isScheduleDate = (dictScheduleApmMapper.selectCount(dateQuery) > 0);
                if (isScheduleDate) {
                    resourceMark.add(DATE_REGULAR);
                } else {
                    QueryWrapper<DictScheduleApm> weekQuery = new QueryWrapper<>();
                    weekQuery.in("QUEUE_NAME", queueNameList);
                    weekQuery.eq("DATE_START", dateStart);
                    weekQuery.eq("DATE_END", dateEnd);
                    weekQuery.eq("TIME_START", timeStart);
                    weekQuery.eq("TIME_END", timeEnd);
                    weekQuery.ne("STOP_FLAG", "2");
                    weekQuery.eq("WEEK_DATE", DateUtil.getWeek(date));
                    if (StringUtils.isBlank(apmType)) {
                        weekQuery.isNull("APM_TYPE");
                    } else {
                        weekQuery.eq("APM_TYPE", apmType);
                    }
                    isScheduleDate = (dictScheduleApmMapper.selectCount(weekQuery) > 0);
                    if (isScheduleDate) {
                        resourceMark.add(WEEK_REGULAR);
                    } else {
                        resourceMark.add(COMMON_REGULAR);
                    }
                }
            }
        }
        map.put("resourceMark", resourceMark);
        return map;
    }

    @Override
    public JsonResult getWholeSourceList(DictScheduleApmDto dto) {
        if (!isCycleRange(dto)) {
            return JsonResultUtil.failure("此周期下未查询到号源信息");
        }
        DictScheduleApmDto dsa = new DictScheduleApmDto();
        dsa.setQueueNames(CommonUtil.split2List(dto.getQueueName()));
        dsa.setTimeStart(dto.getTimeStart());
        dsa.setTimeEnd(dto.getTimeEnd());
        dsa.setDateStart(dto.getDateStart());
        dsa.setDateEnd(dto.getDateEnd());
        dsa.setWeekDate(dto.getWeekDate());
        dsa.setScheduleDate(dto.getScheduleDate());
        String apmType = dto.getApmType();
        if (Regular_Type.equals(apmType)) {
            apmType = null;
        }
        dsa.setApmType(apmType);
        List<DictScheduleApmDto> commRList = dictScheduleApmMapper.getExamQueueApm(dsa);
        List<DictScheduleApmDto> ampList = new ArrayList<>();
        if (StringUtils.isBlank(dto.getScheduleDate()) && StringUtils.isBlank(dto.getWeekDate())) {
            return JsonResultUtil.success("成功", getScheduleQueueDetailSum(commRList, dto.getExamClass()));
        }
        if (StringUtils.isNotBlank(dto.getScheduleDate())) {
            dsa.setWeekDate(DateUtil.getWeek(dto.getScheduleDate()));
        }
        if (commRList != null && commRList.size() > 0) {
            for (DictScheduleApmDto dictScheduleApmDto : commRList) {
                List<DictScheduleApmDto> examQueueList = new ArrayList<>();
                dsa.setQueueName(dictScheduleApmDto.getQueueName());
                if (StringUtils.isNotBlank(dto.getScheduleDate())) {
                    examQueueList = dictScheduleApmMapper.getOneDateExamQueueApm(dsa);
                }
                boolean isEntry = false;
                if (examQueueList != null && examQueueList.size() > 0) {
                    ampList.addAll(examQueueList);
                    isEntry = true;
                }
                if (!isEntry) {
                    examQueueList = dictScheduleApmMapper.getOneWeekExamQueueApm(dsa);
                    if (examQueueList != null && examQueueList.size() > 0) {
                        ampList.addAll(examQueueList);
                        isEntry = true;
                    }
                }
                if (!isEntry) {
                    ampList.add(dictScheduleApmDto);
                }
            }
        }
        getRegularDef(ampList);
        return JsonResultUtil.success("成功", getScheduleQueueDetailSum(ampList, dto.getExamClass()));
    }

    public List<DictScheduleApmDto> getScheduleQueueDetailSum(List<DictScheduleApmDto> ampList, String examClass) {
        ExamScheduleDto examScheduleDto = new ExamScheduleDto();
        String date = DateUtil.addDateStr(new Date(), -1, DateUtil.FORMAT_DATE);
        examScheduleDto.setStartDate(date);
        examScheduleDto.setEndDate(date);
        examScheduleDto.setExamClass(examClass);
        for (DictScheduleApmDto dsa : ampList) {
            examScheduleDto.setQueueName(dsa.getQueueName());
            examScheduleDto.setScheduleApm(dsa.getScheduleApm());
            Map<String, Object> mapResult = examScheduleService.getScheduleQueueDetailSum(examScheduleDto);
            if (mapResult != null) {
                List<String> apmSumList = (List<String>) mapResult.get("apmSum");
                String detailSum = apmSumList.get(0);
                String[] arr = detailSum.split("/");
                if (arr.length > 2) {
                    detailSum = arr[1] + "/" + arr[2];
                }
                dsa.setDetailSum(detailSum);
            }
            dsa.setCurrTime(date);
        }
        getRegularDef(ampList);
        return ampList;
    }

    @Override
    public JsonResult getScheduleApmByCycle(DictScheduleApmDto apm) {
        List<DictScheduleApm> list = dictScheduleApmService.getList(apm);
        HashMap<String, String> apmMap = new HashMap<String, String>();
        List<DictScheduleApmDto> bigArryList = new ArrayList<>();
        List<DictScheduleApmDto> minArryList = new ArrayList<>();
        ArrayList<DictScheduleApmDto> arrayList = new ArrayList<>();
        for (DictScheduleApm dictScheduleApm : list) {
            DictScheduleApmDto scheduleApmDto = new DictScheduleApmDto();
            BeanUtils.copyProperties(dictScheduleApm, scheduleApmDto);
            String timeEnd = dictScheduleApm.getTimeEnd();
            String time = DateUtil.addOrSubtractTime(timeEnd, 1L, false);
            scheduleApmDto.setScheduleApmScope(dictScheduleApm.getTimeStart() + "-" + time);
            String mergeApmCode = dictScheduleApm.getMergeApmCode();
            if (StringUtils.isNotBlank(mergeApmCode)) {
                apmMap.put(mergeApmCode, mergeApmCode);
            }
            String apmType = dictScheduleApm.getApmType();
            if (StringUtils.isNotBlank(apmType) && apmType.equals("1")) {
                String apmCode = dictScheduleApm.getApmCode();
                apmMap.put(apmCode, apmCode);
            }
            arrayList.add(scheduleApmDto);
        }
        for (DictScheduleApmDto scheduleApmDto2 : arrayList) {
            String code = apmMap.get(scheduleApmDto2.getApmCode());
            if (StringUtils.isNotBlank(code)) {
                bigArryList.add(scheduleApmDto2);
            } else {
                minArryList.add(scheduleApmDto2);
            }
        }
        List<DictScheduleApmDto> bigList = nodup(bigArryList);
        List<DictScheduleApmDto> minList = nodup(minArryList);
        Collections.sort(bigList, (o1, o2) -> {
            if (o1.getTimeStart().compareTo(o2.getTimeStart()) != 0) {
                return o1.getTimeStart().compareTo(o2.getTimeStart());
            }
            if (o1.getTimeEnd().compareTo(o2.getTimeEnd()) < 0) {
                return -1;
            }
            return 1;
        });
        Collections.sort(minList, (o1, o2) -> {
            if (o1.getTimeStart().compareTo(o2.getTimeStart()) != 0) {
                return o1.getTimeStart().compareTo(o2.getTimeStart());
            }
            if (o1.getTimeEnd().compareTo(o2.getTimeEnd()) < 0) {
                return -1;
            }
            return 1;
        });
        HashMap<String, List<DictScheduleApmDto>> map = new HashMap<String, List<DictScheduleApmDto>>();
        map.put("big", bigList);
        map.put("min", minList);
        return JsonResultUtil.success(map);
    }

    private List<DictScheduleApmDto> nodup(List<DictScheduleApmDto> arryList) {
        HashMap<String, DictScheduleApmDto> map = new HashMap<>();
        List<DictScheduleApmDto> dtoList = new ArrayList<>();
        for (DictScheduleApmDto apmDto : arryList) {
            String key = apmDto.getTimeStart() + "-" + apmDto.getTimeEnd();
            DictScheduleApmDto scheduleApmDto = map.get(key);
            if (scheduleApmDto != null) {
                String oldName = scheduleApmDto.getQueueName();
                String currQueueName = apmDto.getQueueName();
                String currapmCode = scheduleApmDto.getApmCode();
                String mergeApmCode = apmDto.getApmCode();
                String replaceAll = oldName.replaceAll(currQueueName, "");
                if (!oldName.equals(currQueueName) && replaceAll.length() == oldName.length()) {
                    oldName = oldName + "," + currQueueName;
                    if (StringUtils.isNotBlank(mergeApmCode)) {
                        mergeApmCode = mergeApmCode + "," + currapmCode;
                    } else {
                        mergeApmCode = currapmCode;
                    }
                    scheduleApmDto.setMergeApmCode(mergeApmCode);
                    scheduleApmDto.setQueueName(oldName);
                }
                scheduleApmDto.setMergeApmCode(mergeApmCode);
                scheduleApmDto.setQueueName(oldName);
                map.put(key, scheduleApmDto);
            } else {
                apmDto.setMergeApmCode(apmDto.getApmCode());
                map.put(key, apmDto);
            }
        }
        Set<String> strings = map.keySet();
        for (String string : strings) {
            DictScheduleApmDto schedule = map.get(string);
            dtoList.add(schedule);
        }
        return dtoList;
    }

    @Transactional
    @Override
    public String enableOrDisable(DictScheduleApmDto apm) {
        removeSourceCache();
        Boolean checkDate = false;
        Boolean isCopyRule = apm.getIsCopyRule();
        if (isCopyRule == null) {
            isCopyRule = true;
        }
        String oldApmCode = apm.getApmCode();
        String weekDate = apm.getWeekDate();
        String scheduleDate = apm.getScheduleDate();
        String stopFlag = apm.getStopFlag();
        String operateName = ConstantsUtil.OperateName.OPEN.getDesc();
        if (StringUtils.isNotBlank(apm.getStopFlag()) && apm.getStopFlag().equals("1")) {
            operateName = ConstantsUtil.OperateName.STOP.getDesc();
        }
        DictScheduleApmDto dto = new DictScheduleApmDto();
        DictScheduleApm scheduleApm = dictScheduleApmService.selectOneByApmCode(oldApmCode);
        String apmOldApmCode = apm.getOldApmCode();
        if (scheduleApm == null) {
            throw new BusinessException("查询不到号源信息");
        }
        DictExamQueueDto dictExamQueueDto = new DictExamQueueDto();
        dictExamQueueDto.setQueueName(scheduleApm.getQueueName());
        DictExamQueue examQueue = dictExamQueueServiceImpl.getInfo(dictExamQueueDto);
        String examClass = "";
        if (examQueue != null) {
            examClass = examQueue.getExamClass();
        }
        String resourceMark = apm.getResourceMark();
        String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_COMMON.name();
        if (resourceMark.equals(DATE_REGULAR)) {
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
        } else if (resourceMark.equals(WEEK_REGULAR)) {
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
        }
        ArrayList<String> codeList = new ArrayList<String>();
        String ampCode = scheduleApm.getApmCode();
        String oldResourceMark = COMMON_REGULAR;
        if (StringUtils.isNotBlank(scheduleApm.getWeekDate())) {
            oldResourceMark = WEEK_REGULAR;
        }
        if (StringUtils.isNotBlank(scheduleApm.getScheduleDate())) {
            oldResourceMark = DATE_REGULAR;
            String apmScheduleDate = apm.getScheduleDate();
            if (StringUtils.isNotBlank(apmScheduleDate) && apmScheduleDate.equals(scheduleApm.getScheduleDate())) {
                checkDate = true;
            }
        }
        if (oldResourceMark.equals(resourceMark) && (checkDate || StringUtils.isBlank(scheduleDate))) {
            scheduleApm.setStopFlag(apm.getStopFlag());
            DictScheduleApmDto apmDto = encapsulationSource(scheduleApm);
            if (StringUtils.isNotBlank(stopFlag) && stopFlag.equals(Regular_Type) && StringUtils.isBlank(scheduleApm.getApmType())) {
                DictScheduleApm dictScheduleApm = dictScheduleApmService.selectOneByApmCode(scheduleApm.getApmCode());
                DictScheduleApm bigSchedule = dictScheduleApmService.getBigSchedule(dictScheduleApm);
                dictScheduleApm.setMergeApmCode(null);
                if (bigSchedule != null) {
                    dictScheduleApm.setMergeApmCode(bigSchedule.getApmCode());
                }
                if (bigSchedule != null && scheduleApm.getApmCode().equals(bigSchedule)) {
                    dictScheduleApm.setMergeApmCode(null);
                }
            }
            String apmType = scheduleApm.getApmType();
            if (StringUtils.isBlank(apmType) || apmType.equals("null")) {
                scheduleApm.setDeviceCount((Double) null);
                scheduleApm.setDeviceTask((Double) null);
            }
            apmDto.setResourceMark(resourceMark);
            apmDto.setExamClass(examClass);
            examSyslogService.saveExamSyslogForDesc(moduleName, operateName, apmDto);
            dictScheduleApmService.updateById(scheduleApm);
            return scheduleApm.getApmCode();
        }
        scheduleApm.setApmCode(null);
        DictScheduleApmDto scheduleApmDto = new DictScheduleApmDto();
        scheduleApmDto.setQueueName(scheduleApm.getQueueName());
        scheduleApmDto.setDateEnd(scheduleApm.getDateEnd());
        scheduleApmDto.setDateStart(scheduleApm.getDateStart());
        scheduleApmDto.setTimeStart(scheduleApm.getTimeStart());
        scheduleApmDto.setTimeEnd(scheduleApm.getTimeEnd());
        scheduleApmDto.setWeekDate(weekDate);
        scheduleApmDto.setScheduleDate(scheduleDate);
        DictScheduleApm info = new DictScheduleApm();
        info = dictScheduleApmService.getInfo(scheduleApmDto);
        if (info != null) {
            info.setStopFlag(stopFlag);
            BeanUtils.copyProperties(info, scheduleApm);
            dictScheduleApmService.updateById(scheduleApm);
            ampCode = scheduleApm.getApmCode();
        }
        if (StringUtils.isBlank(scheduleApm.getApmCode())) {
            if (StringUtils.isNotBlank(scheduleDate)) {
                String cylce = scheduleApm.getDateStart() + "~" + scheduleApm.getDateEnd();
                boolean isCycle = DateUtil.checkCurrentTimeIsCycle(cylce, DateUtil.parse(scheduleDate, DateUtil.FORMAT_DATE));
                if (!isCycle) {
                    throw new BusinessException("日期不在周期中");
                }
            }
            DictScheduleApm dictScheduleApm2 = null;
            if (StringUtils.isNotBlank(scheduleDate)) {
                scheduleApmDto.setWeekDate(null);
                scheduleApmDto.setScheduleDate(scheduleDate);
                dictScheduleApm2 = dictScheduleApmService.getInfo(scheduleApmDto);
            }
            if (dictScheduleApm2 == null) {
                if (StringUtils.isBlank(weekDate) && StringUtils.isNotBlank(scheduleDate)) {
                    weekDate = DateUtil.getWeek(scheduleDate);
                }
                if (StringUtils.isNotBlank(weekDate)) {
                    scheduleApmDto.setWeekDate(weekDate);
                    scheduleApmDto.setScheduleDate(null);
                    dictScheduleApm2 = dictScheduleApmService.getInfo(scheduleApmDto);
                }
            }
            if (dictScheduleApm2 == null) {
                scheduleApmDto.setWeekDate(null);
                scheduleApmDto.setScheduleDate(null);
                dictScheduleApm2 = dictScheduleApmService.getInfo(scheduleApmDto);
            }
            if (dictScheduleApm2 == null) {
                throw new BusinessException("未查询到号源");
            }
            BeanUtils.copyProperties(dictScheduleApm2, scheduleApm);
            scheduleApm.setStopFlag(apm.getStopFlag());
            if (resourceMark.equals(DATE_REGULAR)) {
                scheduleApm.setScheduleDate(scheduleDate);
                scheduleApm.setWeekDate(null);
            }
            if (resourceMark.equals(WEEK_REGULAR)) {
                scheduleApm.setWeekDate(weekDate);
                scheduleApm.setScheduleDate(null);
            }
            DictScheduleApm bigSchedule2 = dictScheduleApmService.getBigSchedule(scheduleApm);
            if (bigSchedule2 != null && StringUtils.isBlank(scheduleApm.getApmType())) {
                scheduleApm.setMergeApmCode(bigSchedule2.getApmCode());
            } else {
                scheduleApm.setMergeApmCode(null);
            }
            String code = dictSerialService.getSerialId("APM_CODE");
            scheduleApm.setApmCode(code);
            scheduleApm.setStopFlag(stopFlag);
            scheduleApm.setMergeApmCode(null);
            String apmType2 = scheduleApm.getApmType();
            if (StringUtils.isBlank(apmType2)) {
                scheduleApm.setDeviceCount((Double) null);
                scheduleApm.setDeviceTask((Double) null);
            }
            dictScheduleApmService.save(scheduleApm);
            DictScheduleApmDto apmDto2 = encapsulationSource(scheduleApm);
            apmDto2.setResourceMark(resourceMark);
            apmDto2.setExamClass(examClass);
            examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.INSERT.getDesc(), apmDto2);
            ampCode = code;
        }
        if (isCopyRule) {
            if (StringUtils.isNotBlank(apmOldApmCode)) {
                oldApmCode = apmOldApmCode;
            }
            DictScheduleApmRegularDto apmRegularDto = new DictScheduleApmRegularDto();
            apmRegularDto.setApmCode(ampCode);
            apmRegularDto.setOldApmCode(oldApmCode);
            dictScheduleApmRegularService.saveRegular(apmRegularDto);
        }
        return ampCode;
    }

    private DictScheduleApmDto encapsulationSource(DictScheduleApm dictScheduleApm) {
        DictScheduleApmDto scheduleApmDto = new DictScheduleApmDto();
        BeanUtils.copyProperties(dictScheduleApm, scheduleApmDto);
        return scheduleApmDto;
    }

    @Override
    public JsonResult manyDateEnableOrdisable(DictScheduleApmDto apm) {
        String scheduleDate = apm.getScheduleDate();
        List<String> stringList = CommonUtil.split2List(scheduleDate);
        apm.setResourceMark(DATE_REGULAR);
        for (String date : stringList) {
            apm.setScheduleDate(date);
            enableOrDisable(apm);
        }
        return JsonResultUtil.success();
    }

    @Override
    public JsonResult batchEnableOrDisable(DictScheduleApmDto apm) {
        String apmCode = apm.getApmCode();
        List<String> apmCodeList = CommonUtil.split2List(apmCode);
        for (String code : apmCodeList) {
            apm.setApmCode(code);
            enableOrDisable(apm);
        }
        return JsonResultUtil.success();
    }

    @Transactional
    @Override
    public String updateScheduleApm(DictScheduleApmDto apm) {
        String resourceMark = apm.getResourceMark();
        String mergeApmCode = apm.getMergeApmCode();
        String apmCode = apm.getApmCode();
        String clearIsDeviceTask = apm.getClearIsDeviceTask();
        if (StringUtils.isBlank(clearIsDeviceTask)) {
            clearIsDeviceTask = Regular_Type;
        }
        Double task = apm.getDeviceTask();
        String oldApmCode = apm.getOldApmCode();
        Double deviceCount = apm.getDeviceCount();
        Double deviceTask = apm.getDeviceTask();
        boolean checkDate = false;
        DictScheduleApm dictScheduleApm = dictScheduleApmService.selectOneByApmCode(apmCode);
        if (dictScheduleApm == null) {
            throw new BusinessException("当前号源查询不到");
        }
        DictExamQueueDto dictExamQueueDto = new DictExamQueueDto();
        dictExamQueueDto.setQueueName(dictScheduleApm.getQueueName());
        DictExamQueue examQueue = dictExamQueueServiceImpl.getInfo(dictExamQueueDto);
        String examClass = "";
        if (examQueue != null) {
            examClass = examQueue.getExamClass();
        }
        String infoResourceMark = COMMON_REGULAR;
        String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_COMMON.name();
        if (StringUtils.isNotBlank(dictScheduleApm.getWeekDate())) {
            infoResourceMark = WEEK_REGULAR;
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
        }
        String oldScheduleDate = dictScheduleApm.getScheduleDate();
        if (StringUtils.isNotBlank(oldScheduleDate)) {
            infoResourceMark = DATE_REGULAR;
            moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
            String scheduleDate = apm.getScheduleDate();
            if (StringUtils.isNotBlank(scheduleDate) && scheduleDate.equals(oldScheduleDate)) {
                checkDate = true;
            }
        }
        double sum = 0.0;
        dictScheduleApm.setDeviceCount(deviceCount);
        dictScheduleApm.setDeviceTask(deviceTask);
        Double maxLimit = apm.getMaxLimit();
        if (deviceCount != null && deviceTask != null) {
            sum = deviceCount * deviceTask;
            dictScheduleApm.setMaxLimit(sum);
        }
        if (maxLimit != null && !maxLimit.equals(sum) && deviceCount != null && deviceTask != null) {
            dictScheduleApm.setDeviceTask((Double) null);
            throw new BusinessException("号源数与设备设置不一致");
        }
        if (maxLimit != null) {
            dictScheduleApm.setMaxLimit(maxLimit);
        }
        if (dictScheduleApm == null) {
            throw new BusinessException("要更新的号源不存在");
        }
        if (StringUtils.isBlank(resourceMark)) {
            String apmType = dictScheduleApm.getApmType();
            if (StringUtils.isBlank(apmType)) {
                dictScheduleApm.setDeviceCount((Double) null);
                dictScheduleApm.setDeviceTask((Double) null);
            }
            if (task == null && StringUtils.isNotBlank(apmType) && clearIsDeviceTask.equals("1")) {
                dictScheduleApmService.updateTsak(dictScheduleApm);
            }
            DictScheduleApmDto dictScheduleApmDto = encapsulationSource(dictScheduleApm);
            dictScheduleApmDto.setExamClass(examClass);
            dictScheduleApmDto.setResourceMark(infoResourceMark);
            examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.UPDATE.getDesc(), dictScheduleApmDto);
            dictScheduleApmService.updateById(dictScheduleApm);
            return dictScheduleApm.getApmCode();
        }
        if ((StringUtils.isNotBlank(resourceMark) && !resourceMark.equals(infoResourceMark)) || !checkDate) {
            apmCode = enableOrDisable(apm);
            dictScheduleApm = dictScheduleApmService.selectOneByApmCode(apmCode);
        }
        String apmType = dictScheduleApm.getApmType();
        BeanUtils.copyProperties(apm, dictScheduleApm);
        dictScheduleApm.setApmCode(apmCode);
        DictScheduleApm bigSchedule = dictScheduleApmService.getBigSchedule(dictScheduleApm);
        dictScheduleApm.setMergeApmCode(null);
        if (bigSchedule != null && StringUtils.isBlank(apmType)) {
            dictScheduleApm.setMergeApmCode(bigSchedule.getApmCode());
        }
        if (StringUtils.isBlank(apmType)) {
            dictScheduleApm.setDeviceCount(null);
            dictScheduleApm.setDeviceTask(null);
        }
        if (task == null && StringUtils.isNotBlank(apmType) && clearIsDeviceTask.equals("1")) {
            dictScheduleApmService.updateTsak(dictScheduleApm);
        }
        DictScheduleApmDto dictScheduleApmDto2 = encapsulationSource(dictScheduleApm);
        dictScheduleApmDto2.setExamClass(examClass);
        dictScheduleApmDto2.setResourceMark(resourceMark);
        examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.UPDATE.getDesc(), dictScheduleApmDto2);
        dictScheduleApmService.updateById(dictScheduleApm);
        return dictScheduleApm.getApmCode();
    }

    @Transactional
    @Override
    public JsonResult batchUpdateScheduleApm(DictScheduleApmDto apm) {
        String apmCode = apm.getApmCode();
        String resourceMark = apm.getResourceMark();
        List<String> apmCodeList = (List<String>) CommonUtil.split2List(apmCode);
        for (String code : apmCodeList) {
            apm.setApmCode(code);
            updateScheduleApm(apm);
        }
        return JsonResultUtil.success();
    }

    @Transactional
    @Override
    public JsonResult wholeCancelModify(DictScheduleApmDto dto) {
        removeSourceCache();
        List<String> queueNameList = CommonUtil.split2List(dto.getQueueName());
        for (String queueName : queueNameList) {
            String resourceMark = DATE_REGULAR;
            String moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_DATE.name();
            if (StringUtils.isNotBlank(dto.getWeekDate())) {
                resourceMark = WEEK_REGULAR;
                moduleName = ConstantsUtil.ModuleName.DICT_SCHEDULE_APM_WEEK.name();
            }
            dto.setQueueName(queueName);
            DictScheduleApm dsa = dictScheduleApmService.getInfo(dto);
            if (dsa != null) {
                DictScheduleApm amp = new DictScheduleApm();
                amp.setStopFlag("2");
                QueryWrapper<DictScheduleApm> up = new QueryWrapper<>();
                up.eq("APM_CODE", dsa.getApmCode());
                dictScheduleApmMapper.update(amp, up);
                QueryWrapper<DictScheduleApmRegular> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("APM_CODE", dsa.getApmCode());
                dictScheduleApmRegularMapper.delete(queryWrapper);
                DictScheduleApmDto dictScheduleApm = new DictScheduleApmDto();
                dictScheduleApm.setExamClass(dto.getExamClass());
                dictScheduleApm.setQueueName(queueName);
                dictScheduleApm.setApmCode(dsa.getApmCode());
                dictScheduleApm.setResourceMark(resourceMark);
                examSyslogService.saveExamSyslogForDesc(moduleName, ConstantsUtil.OperateName.DELETE.getDesc(), dictScheduleApm);
            }
        }
        return JsonResultUtil.success("成功");
    }

    @Transactional
    @Override
    public JsonResult batchUpdateBigScheduleApm(DictScheduleApmDto apm) {
        Boolean isCopyData = apm.getIsCopyData();
        Boolean isCopyRule = apm.getIsCopyRule();
        if (isCopyData == null) {
            isCopyData = false;
        }
        if (isCopyRule == null) {
            isCopyRule = true;
        }
        String mergeApmCode = apm.getMergeApmCode();
        String scheduleApmStr = apm.getScheduleApm();
        String scheduleDate = apm.getScheduleDate();
        String weekDate = apm.getWeekDate();
        String resourceMark = apm.getResourceMark();
        List<String> mergeApmCodeList = CommonUtil.split2List(mergeApmCode);
        apm.setMergeApmCodeList(mergeApmCodeList);
        apm.setApmCode(null);
        Map<String, List<String>> hashMap = new HashMap<String, List<String>>();
        Map<String, DictScheduleApm> scheduleMap = new HashMap<>();
        Double deviceCount = apm.getDeviceCount();
        Double deviceTask = apm.getDeviceTask();
        Double maxLimit = apm.getMaxLimit();
        String stopFlag = apm.getStopFlag();
        double sum = 0.0;
        if (deviceCount != null && deviceTask != null) {
            sum = deviceCount * deviceTask;
            apm.setDeviceCount(deviceCount);
            apm.setDeviceTask(deviceTask);
            apm.setMaxLimit(sum);
        }
        if (maxLimit != null && !maxLimit.equals(sum) && deviceCount != null && deviceTask != null) {
            throw new BusinessException("号源数与设备设置不一致");
        }
        if (maxLimit != null) {
            apm.setMaxLimit(maxLimit);
        }
        DictScheduleApmDto apmDto = new DictScheduleApmDto();
        String oldResourceMark = COMMON_REGULAR;
        if (StringUtils.isNotBlank(apm.getWeekDate())) {
            oldResourceMark = WEEK_REGULAR;
        }
        if (StringUtils.isNotBlank(apm.getScheduleDate())) {
            oldResourceMark = DATE_REGULAR;
        }
        for (String mergeCode : mergeApmCodeList) {
            List<String> arrayList = new ArrayList<String>();
            apmDto.setMergeApmCode(mergeCode);
            List<DictScheduleApm> scheduleApms = dictScheduleApmService.getScheduleByMergeApmCode(apmDto);
            for (DictScheduleApm scheduleApm : scheduleApms) {
                if (scheduleApm.getStopFlag().equals(Regular_Type)) {
                    String apmCode = scheduleApm.getApmCode();
                    arrayList.add(apmCode);
                    scheduleMap.put(apmCode, scheduleApm);
                }
            }
            hashMap.put(mergeCode, arrayList);
        }
        Set<String> keySet = hashMap.keySet();
        for (String key : keySet) {
            apm.setApmCode(key);
            apm.setMaxLimit(maxLimit);
            apm.setDeviceCount(deviceCount);
            apm.setDeviceTask(deviceTask);
            apm.setStopFlag(stopFlag);
            apm.setResourceMark(resourceMark);
            apm.setScheduleApm(scheduleApmStr);
            apm.setMergeApmCode(null);
            String apmcode = updateScheduleApm(apm);
            List<String> codes = hashMap.get(key);
            int size = codes.size();
            int value = 0;
            int val = 0;
            if (maxLimit != null && size > 0) {
                value = (int) (maxLimit % size);
                val = (int) (maxLimit / size);
            }
            int v = size - value;
            int index = 0;
            for (String code : codes) {
                DictScheduleApmDto scheduleApmDto = new DictScheduleApmDto();
                DictScheduleApm dictScheduleApm = scheduleMap.get(code);
                if (isCopyData) {
                    BeanUtils.copyProperties(dictScheduleApm, scheduleApmDto);
                }
                scheduleApmDto.setMergeApmCode(apmcode);
                scheduleApmDto.setApmCode(code);
                scheduleApmDto.setDeviceCount(deviceCount);
                scheduleApmDto.setDateEnd(dictScheduleApm.getDateEnd());
                scheduleApmDto.setDateStart(dictScheduleApm.getDateStart());
                scheduleApmDto.setTimeEnd(dictScheduleApm.getTimeEnd());
                scheduleApmDto.setTimeStart(dictScheduleApm.getTimeStart());
                scheduleApmDto.setQueueName(dictScheduleApm.getQueueName());
                scheduleApmDto.setScheduleDate(scheduleDate);
                scheduleApmDto.setWeekDate(weekDate);
                scheduleApmDto.setResourceMark(resourceMark);
                scheduleApmDto.setIsCopyData(isCopyData);
                scheduleApmDto.setIsCopyRule(isCopyRule);
                scheduleApmDto.setOldApmCode(dictScheduleApm.getApmCode());
                if (maxLimit == null) {
                    scheduleApmDto.setMaxLimit((Double) null);
                }
                if (value == 0 && maxLimit != null) {
                    scheduleApmDto.setMaxLimit(Double.valueOf((double) val));
                }
                if (value > 0 && value < size && maxLimit != null) {
                    scheduleApmDto.setMaxLimit(Double.valueOf((double) val));
                    if (index >= v) {
                        scheduleApmDto.setMaxLimit(Double.valueOf(val + 1.0));
                    }
                }
                scheduleApmDto.setDeviceTask((Double) null);
                updateScheduleApm(scheduleApmDto);
                ++index;
            }
        }
        return JsonResultUtil.success();
    }

    @Transactional
    @Override
    public JsonResult batchCopyBigScheduleApm(DictScheduleApmDto apm) {
        String apmCode = apm.getApmCode();
        String resourceMark = apm.getResourceMark();
        String apmApmType = apm.getApmType();
        List<String> apmCodeCopyRuleList = (List<String>) CommonUtil.strToList(apmCode, ",");
        Map<String, List<String>> apmCodeMap = new HashMap<String, List<String>>();
        for (String apmCodeCopyRule : apmCodeCopyRuleList) {
            List<String> copyRuleList = (List<String>) CommonUtil.strToList(apmCodeCopyRule, "-");
            apmCodeMap.put(copyRuleList.get(0), copyRuleList);
        }
        String scheduleDate = apm.getScheduleDate();
        List<String> dateList = (List<String>) CommonUtil.strToList(scheduleDate, ",");
        Set<String> apmCodeSet = apmCodeMap.keySet();
        for (String date : dateList) {
            for (String code : apmCodeSet) {
                DictScheduleApmDto dictScheduleApmDto = new DictScheduleApmDto();
                List<String> copyRuleList2 = apmCodeMap.get(code);
                DictScheduleApm dictScheduleApm = dictScheduleApmService.selectOneByApmCode(code);
                if (dictScheduleApm == null) {
                    return JsonResultUtil.failure("查询不到复制原型号源");
                }
                String data = copyRuleList2.get(1);
                BeanUtils.copyProperties(dictScheduleApm, dictScheduleApmDto);
                dictScheduleApmDto.setScheduleDate(date);
                dictScheduleApmDto.setResourceMark(resourceMark);
                dictScheduleApmDto.setOldApmCode(dictScheduleApm.getApmCode());
                dictScheduleApmDto.setIsCopyData(Boolean.TRUE);
                if (data.equals(Regular_Type)) {
                    dictScheduleApmDto.setIsCopyData(Boolean.FALSE);
                    String oldResourceMark = COMMON_REGULAR;
                    if (StringUtils.isNotBlank(dictScheduleApm.getWeekDate())) {
                        oldResourceMark = WEEK_REGULAR;
                    }
                    if (StringUtils.isNotBlank(dictScheduleApm.getScheduleDate())) {
                        oldResourceMark = DATE_REGULAR;
                    }
                    DictScheduleApmDto apmDto = new DictScheduleApmDto();
                    apmDto.setScheduleDate(date);
                    apmDto.setDateEnd(dictScheduleApm.getDateEnd());
                    apmDto.setDateStart(dictScheduleApm.getDateStart());
                    apmDto.setTimeEnd(dictScheduleApm.getTimeEnd());
                    apmDto.setTimeStart(dictScheduleApm.getTimeStart());
                    apmDto.setQueueName(dictScheduleApm.getQueueName());
                    DictScheduleApm scheduleApm = dictScheduleApmService.getInfo(apmDto);
                    if (scheduleApm == null) {
                        apmDto.setScheduleDate(null);
                        apmDto.setWeekDate(DateUtil.getWeek(date));
                        scheduleApm = dictScheduleApmService.getInfo(apmDto);
                    }
                    if (scheduleApm == null && !oldResourceMark.equals(COMMON_REGULAR)) {
                        apmDto.setWeekDate(null);
                        scheduleApm = dictScheduleApmService.getInfo(apmDto);
                    }
                    if (scheduleApm == null && oldResourceMark.equals(COMMON_REGULAR)) {
                        scheduleApm = dictScheduleApm;
                    }
                    if (scheduleApm == null) {
                        return JsonResultUtil.failure("该号源不存在");
                    }
                    BeanUtils.copyProperties(scheduleApm, dictScheduleApmDto);
                    dictScheduleApmDto.setScheduleDate(date);
                    dictScheduleApmDto.setIsCopyData(apmDto.getIsCopyData());
                    dictScheduleApmDto.setIsCopyRule(apmDto.getIsCopyRule());
                    dictScheduleApmDto.setResourceMark(resourceMark);
                }
                String rule = copyRuleList2.get(2);
                dictScheduleApmDto.setIsCopyRule(Boolean.valueOf(true));
                if (rule.equals(Regular_Type)) {
                    dictScheduleApmDto.setIsCopyRule(Boolean.valueOf(false));
                }
                dictScheduleApmDto.setMergeApmCode(code);
                if (StringUtils.isBlank(dictScheduleApmDto.getApmType())) {
                    dictScheduleApmDto.setApmCode(dictScheduleApm.getApmCode());
                }
                dictScheduleApmDto.setWeekDate(null);
                if (StringUtils.isNotBlank(apmApmType) && apmApmType.equals("1")) {
                    batchUpdateBigScheduleApm(dictScheduleApmDto);
                }
                if (!StringUtils.isBlank(apmApmType)) {
                    continue;
                }
                dictScheduleApmDto.setOldApmCode(code);
                updateScheduleApm(dictScheduleApmDto);
            }
        }
        return JsonResultUtil.success();
    }

    @Override
    public JsonResult batchModifyMinSchedule(DictScheduleApmDto apm) {
        String apmCode = apm.getApmCode();
        String queueName = apm.getQueueName();
        List<String> queuNames = CommonUtil.split2List(queueName);
        List<String> apmCodes = CommonUtil.split2List(apmCode);
        for (String code : apmCodes) {
            DictScheduleApm scheduleApm = dictScheduleApmService.selectOneByApmCode(code);
            String apmQueueName = scheduleApm.getQueueName();
            for (String queuName : queuNames) {
                if (apmQueueName.equals(queuName)) {
                    apm.setApmCode(code);
                    apm.setDateStart(scheduleApm.getDateStart());
                    apm.setDateEnd(scheduleApm.getDateEnd());
                    apm.setTimeEnd(scheduleApm.getTimeEnd());
                    apm.setTimeStart(scheduleApm.getTimeStart());
                    apm.setQueueName(scheduleApm.getQueueName());
                    batchModifySchedule(apm);
                }
            }
        }
        return JsonResultUtil.success();
    }

    @Transactional
    @Override
    public JsonResult saveScheduleBatchApm(DictScheduleApmBatchDto dto) {
        DictScheduleApmDto dictScheduleApmDto = new DictScheduleApmDto();
        dto.getDictScheduleApmDtos().stream().forEach(item -> {
            BeanUtils.copyProperties(item, dictScheduleApmDto);
            dictScheduleApmDto.setScheduleApm(dto.getScheduleApm());
            dictScheduleApmDto.setQueueName(dto.getQueueName());
            dictScheduleApmDto.setRegularDefSchedule(dto.getRegularDefSchedule());
            dictScheduleApmDto.setRegularDefScheduleName(dto.getRegularDefScheduleName());
            dictScheduleApmDto.setRegularSchedule(dto.getRegularSchedule());
            dictScheduleApmDto.setRegularScheduleName(dto.getRegularScheduleName());
            dictScheduleApmDto.setExamClass(dto.getExamClass());
            dictScheduleApmDto.setDateStart(dto.getDateStart());
            dictScheduleApmDto.setDateEnd(dto.getDateEnd());
            dictScheduleApmDto.setStopFlag(dto.getStopFlag());
            if (dictScheduleApmDto.getTimeInterval() != null) {
                ArrayList<DictScheduleApmDto> dictScheduleApmDtos = new ArrayList<>();
                String[] arr = dictScheduleApmDto.getScheduleApmScope().split("~");
                Date dateEnd = DateUtil.parse(arr[1], DateUtil.FORMAT_HHMM);
                Date dateStart = DateUtil.parse(arr[0], DateUtil.FORMAT_HHMM);
                Integer timeInterval = dictScheduleApmDto.getTimeInterval();
                int timeSpan = DateUtil.getIntervalMinus(dateStart, dateEnd);
                if (Objects.isNull(timeInterval) || timeInterval <= 0) {
                    timeInterval = timeSpan;
                }
                if (dateStart.compareTo(dateEnd) >= 0) {
                    throw new BusinessException("时段开始时间不能大于结束时间！");
                }
                int intervalMinus = timeSpan % timeInterval;
                if (intervalMinus != 0) {
                    throw new BusinessException("切割时段区间失败！");
                }
                List<String> time = new ArrayList<>();
                try {
                    time = DateUtil.findDates("N", dateStart, dateEnd, timeInterval);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                for (int i = 0; i < time.size() - 1; i++) {
                    DictScheduleApmDto dictScheduleApmDto1 = new DictScheduleApmDto();
                    BeanUtils.copyProperties(dictScheduleApmDto, dictScheduleApmDto1);
                    dictScheduleApmDto1.setScheduleApmScope(time.get(i) + "~" + time.get(i + 1));
                    dictScheduleApmDtos.add(dictScheduleApmDto1);
                }
                dictScheduleApmDtos.stream().forEach(vo -> {
                    JsonResult jsonResult = saveScheduleApm(vo);
                    if (!jsonResult.getStatus().equals(ErrorCode.SUCCESS.getKey())) {
                        throw new BusinessException(jsonResult.getMessage());
                    }
                });
            }
            saveScheduleApm(dictScheduleApmDto);
        });
        return JsonResultUtil.success("成功");
    }
}
